diff --git a/CHANGELOG.md b/CHANGELOG.md index 25b7c560..4f27994f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -124,4 +124,4 @@ All notable changes to this project will be documented in this file. The format - **If an account attempts to install a second CEP-78 contract with the same name, it will overwrite the access rights and render the first instance unusable.** -[Keep a Changelog]: https://keepachangelog.com/en/1.0.0 +[Keep a Changelog]: https://keepachangelog.com/en/1.0.0 \ No newline at end of file diff --git a/README.md b/README.md index c5611c95..21989055 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,10 @@ The following are the optional parameters that can be passed in at the time of i #### 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](/docs/using-casper-client.md). +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](/docs/tutorials/getting-started/full-installation-tutorial.md). ```bash -casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \ +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'" \ @@ -104,15 +104,15 @@ folder within the project folder. ### Checking Token Ownership -[Learn to check token ownership](./tutorials/token-ownership-tutorial.md) starting with version [v1.1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1). The `OwnerReverseLookupMode` modality must be set to `Complete` as described [here](/docs/reverse-lookup.md). +[Learn to check token ownership](./docs/tutorials/token-ownership-tutorial.md) starting with version [v1.1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1). The `OwnerReverseLookupMode` modality must be set to `Complete` as described [here](/docs/reverse-lookup.md). ### Upgrading to Version 1.1.1 -Upgrade to v1.1.1 using a [Standard NamedKey Convention](./tutorials/standard-migration-tutorial.md) or a [Custom NamedKey Convention](./tutorials/custom-migration-tutorial.md). +Upgrade to v1.1.1 using a [Standard NamedKey Convention](./docs/tutorials/standard-migration-tutorial.md) or a [Custom NamedKey Convention](./docs/tutorials/custom-migration-tutorial.md). ## 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](/docs/using-casper-client.md). +You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client [here](/docs/tutorials/getting-started/full-installation-tutorial.md). ## Test Suite and Specification diff --git a/docs/modalities.md b/docs/modalities.md index 6c97927f..8d2d355f 100644 --- a/docs/modalities.md +++ b/docs/modalities.md @@ -296,8 +296,8 @@ The `OwnerReverseLookupMode` modality is set at install and determines if a give This modality provides the following options: 1. `NoLookup`: The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling. -2. `Complete`: The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described [here](reverse-lookup.md). -3. `TransfersOnly`: The reporting and receipt functionality is supported like `Complete`. However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described [here](reverse-lookup.md). +2. `Complete`: The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described [here](../docs/reverse-lookup.md#owner-reverse-lookup-functionality). +3. `TransfersOnly`: The reporting and receipt functionality is supported like `Complete`. However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described [here](../docs/reverse-lookup.md#owner-reverse-lookup-functionality). Additionally, when set to `Complete`, causes a receipt to be returned by the `mint` or `transfer` entrypoints, which the caller can store in their account or contract context for later reference. diff --git a/docs/reverse-lookup.md b/docs/reverse-lookup.md index 09bdd2aa..99f01fa3 100644 --- a/docs/reverse-lookup.md +++ b/docs/reverse-lookup.md @@ -1,6 +1,6 @@ # Owner Reverse Lookup Functionality -In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found [here](../tutorials/token-ownership-tutorial.md). +In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found [here](../docs/tutorials/token-ownership-tutorial.md). In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract. diff --git a/tutorials/custom-migration-tutorial.md b/docs/tutorials/custom-migration-tutorial.md similarity index 85% rename from tutorials/custom-migration-tutorial.md rename to docs/tutorials/custom-migration-tutorial.md index b61aa3bc..de42e140 100644 --- a/tutorials/custom-migration-tutorial.md +++ b/docs/tutorials/custom-migration-tutorial.md @@ -8,11 +8,11 @@ This tutorial uses the Casper command-line client to upgrade *and* migrate from - Your v1.0.0 NFT contract instance uses custom NamedKeys for the contract package hash and contract package access URef. - You have the v1.0.0 contract package hash stored under a custom NamedKey in the account that installed the contract. - You have the v1.0.0 contract package access URef stored under a custom NamedKey in the account that installed the contract. -- You understand what is new in [Version 1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1) of the CEP-78 Enhanced NFT Standard. +- You understand what is new in [Version 1.1.0](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.0) of the CEP-78 Enhanced NFT Standard. ## Upgrading and Migrating Terminology -The upgrade to version 1.1.1 involves a data migration to a new [page system](../docs/reverse-lookup.md#the-cep-78-page-system) tracking token ownership. The usual [upgrade](https://docs.casper.network/developers/writing-onchain-code/upgrading-contracts/) process triggers the data migration. For more information, see [Standard Migration Tutorial](standard-migration-tutorial.md#upgrading-and-migrating-terminology). +The upgrade to version 1.1.1 involves a data migration to a new [page system](../reverse-lookup.md#the-cep-78-page-system) tracking token ownership. The usual [upgrade](https://docs.casperlabs.io/dapp-dev-guide/writing-contracts/upgrading-contracts/) process triggers the data migration. For more information, see [Standard Migration Tutorial](standard-migration-tutorial.md#upgrading-and-migrating-terminology). ## Steps to Upgrade to Version 1.1.1 @@ -22,7 +22,7 @@ The `cep-78-wasm` folder contains the `contract.wasm` to send to the network to ### Custom NamedKeys before Migration -The custom migration path assumes that the contract has modified the NamedKey entries created during the v1.0.0. See the example below as well as the [NamedKeyConvention](../docs/modalities.md#namedkeyconventionmode) modality. +The custom migration path assumes that the contract has modified the NamedKey entries created during the v1.0.0. See the example below as well as the [NamedKeyConvention](../modalities.md#namedkeyconventionmode) modality. | NamedKey Pre-Migration | Explanation | |-------------|-------------| @@ -38,8 +38,8 @@ The custom migration path assumes that the contract has modified the NamedKey en When upgrading using the `casper-client`, you must provide four runtime arguments: -- `named_key_convention`: The [NamedKeyConvention](../docs/modalities.md#namedkeyconventionmode) runtime argument as a u8 value equal to 2: `--session-arg "named_key_convention:u8='2'"`. See the [ARG_NAMED_KEY_CONVENTION](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L1991). -- `collection_name`: The collection name specified when the contract was [installed](../docs/using-casper-client.md#installing-the-contract) using the `collection_name` option. See the [contract code](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L93) for details.  +- `named_key_convention`: The [NamedKeyConvention](../modalities.md#namedkeyconventionmode) runtime argument as a u8 value equal to 2: `--session-arg "named_key_convention:u8='2'"`. See the [ARG_NAMED_KEY_CONVENTION](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L1991). +- `collection_name`: The collection name specified when the contract was [installed](./getting-started/full-installation-tutorial.md) using the `collection_name` option. See the [contract code](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L93) for details.  - `hash_key_name`: The custom contract package hash NamedKey as a String. See the [ARG_HASH_KEY_NAME_1_0_0](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L2006). - `access_key_name`: The custom contract package access NamedKey as a String. See the [ARG_ACCESS_KEY_NAME_1_0_0](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L2005). @@ -64,7 +64,7 @@ Here is the full list of required arguments: - `secret-key`: The file name containing the secret key of the account paying for the deploy. - `payment-amount`: The payment for the deploy in motes. - `session-path`: The path to the compiled Wasm on your computer. When using the [cep-78-wasm.tar.gz](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/download/v1.1.1/cep-78-wasm.tar.gz) provided, this would be the path to the `contract.wasm` file. -- `named_key_convention`: Argument that specifies the use of the `V_1_0_standard` [NamedKeyConvention](../docs/modalities.md#namedkeyconventionmode). +- `named_key_convention`: Argument that specifies the use of the `V_1_0_standard` [NamedKeyConvention](../modalities.md#namedkeyconventionmode). - `collection_name`: Argument that specifies the collection name as a String. - `hash_key_name`: The custom contract package hash NamedKey as a String. - `access_key_name`: The custom contract package access NamedKey as a String. @@ -85,7 +85,7 @@ The following is an example of upgrading and migrating to version 1.1.1 of a pre ```bash casper-client put-deploy \ ---node-addres http://65.21.235.219:7777 \ +--node-addres https://rpc.testnet.casperlabs.io/ \ --chain-name "casper-test" \ --secret-key ~/KEYS/secret_key.pem \ --payment-amount 300000000000 \ diff --git a/docs/tutorials/getting-started/full-installation-tutorial.md b/docs/tutorials/getting-started/full-installation-tutorial.md new file mode 100644 index 00000000..be2bbf39 --- /dev/null +++ b/docs/tutorials/getting-started/full-installation-tutorial.md @@ -0,0 +1,1511 @@ +# Installing an NFT Contract using the Rust Casper Client + +This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of `1.63.0`. The code for this tutorial is available in [GitHub](https://github.com/casper-ecosystem/cep-78-enhanced-nft/). A portion of this tutorial reviews the [contract](../../../contract/src/main.rs). + +Information on the modalities used throughout this installation process can be found in the [modalities documentation](modalities.md). + +## Table of Contents + +1. [Environment Setup](#environment-setup) + - [Prerequisites](#prerequisites) + - [Building the Contract and Tests](#building-the-contract-and-tests) +2. [Reviewing the Contract Implementation](#reviewing-the-contract-implementation) + - [Included Crates and Modules](#included-crates-and-modules) + - [Initialization Flow](#Initialization-flow) + - [Contract Entrypoints](#contract-entrypoints) +3. [Installing the Contract](#installing-the-contract) + - [Querying Global State](#querying-global-state) + - [Sending the Installation Deploy](#sending-the-installation-deploy) + - [Verifying the Installation](#verifying-the-installation) +4. [Next Steps](#next-steps) + +## Environment Setup + +### Prerequisites + +Before using this guide, ensure you meet the following requirements: + +- Set up the [development prerequisites](https://docs.casper.network/developers/prerequisites/), including the [Casper client](https://docs.casper.network/developers/prerequisites/#install-casper-client) +- Get a valid [node address](https://docs.casper.network/developers/prerequisites/#acquire-node-address-from-network-peers) from the network +- Know how to install a [smart contract](https://docs.casper.network/developers/cli/sending-deploys/) on a Casper network +- Hold enough CSPR tokens to pay for transactions + +The [Writing Rust Contracts on Casper](https://docs.casper.network/developers/writing-onchain-code/simple-contract/) document outlines many aspects of this tutorial and should be read as a prerequisite. + +### Building the Contract and Tests + +First, clone the contract from GitHub: + +```bash +git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft +``` + +Prepare your environment with the following command: + +```bash +make prepare +``` + +If your environment is set up correctly, you will see this output: + +```bash +rustup target add wasm32-unknown-unknown +info: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date +``` + +If you do not see this message, check the [Getting Started Guide](https://docs.casper.network/developers/writing-onchain-code/getting-started/). + +The contract code can be compiled to Wasm by running the `make build-contract` command provided in the Makefile at the top level. The Wasm will be found in the `contract/target/wasm32-unknown-unknown/release` directory as `contract.wasm`. + +You can also compile your contract and run the contract unit tests with this command: + +```bash +make test +``` + +## Reviewing the Contract Implementation + +In this repository, you will find a library and an [example NFT implementation](../../../contract/src/main.rs) for Casper networks. This section explains the example contract in more detail. + +There are four steps to follow when you intend to create your implementation of the NFT contract, as follows: + +1. Fork the code from the example repository listed above. +2. Perform any necessary customization changes on your fork of the example contract. +3. Compile the customized code to Wasm. +4. Send the customized Wasm as a deploy to a Casper network. + +### Included Crates and Modules + +The contract implementation starts by importing the following essential Casper crates: + +- [casper_contract](https://docs.rs/casper-contract/latest/casper_contract/index.html) - A Rust library for writing smart contracts on Casper networks +- [casper_types](https://docs.rs/casper-types/latest/casper_types/) - Types used to allow the creation of Wasm contracts and tests for use on Casper networks + +The contract code defines additional modules in the `contract/src` folder: + +- `constants` - Constant values required to run the contract code +- `error` - Errors related to the NFT contract +- `events` - A library for contract-emitted events +- `metadata` - A module handling the contract's metadata and corresponding dictionary +- `modalities` - Common expectations around contract usage and behavior +- `utils` - Utility and helper functions to run the contract code + +### Initialization Flow + +Initializing the contract happens through the `call() -> install_contract() -> init()` functions inside the [main.rs](../../../contract/src/main.rs) contract file. The `init()` function reads the runtime arguments and defines parameters such as `collection_name`, `collection_symbol`, and `total_token_supply`, among the other required and optional arguments described in the [README](../../../README.md#required-runtime-arguments). + +### Contract Entrypoints + +This section briefly explains the essential entrypoints used in the Casper NFT contract. To see their full implementation, refer to the [main.rs](../../../contract/src/main.rs) contract file. For further questions, contact the Casper support team via the [Discord channel](https://discord.com/invite/casperblockchain). + +- [**approve**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1002) - Allows a spender to transfer up to an amount of the owners’s tokens +- [**balance_of**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1616) - Returns the token balance of the owner +- [**burn**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L874) - Burns tokens, reducing the total supply +- [**get_approved**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1728) - Returns the hash of the approved account for a specified token identifier +- [**init**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L81) - Sets the collection name, symbol, and total token supply; initializes the allow minting setting, minting mode, ownership mode, NFT kind, holder mode, whitelist mode and contract whitelist, JSON schema, receipt name, identifier mode, and burn mode. This entrypoint can only be called once when the contract is installed on the network +- [**is_approved_for_all**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1328) - Returns yes if an account is approved as an operator for a token owner +- [**metadata**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1675) - Returns the metadata associated with a token identifier +- [**mint**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L619) - Mints additional tokens if minting is allowed, increasing the total supply +- [**owner_of**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1636) - Returns the owner for a specified token identifier +- [**register_owner**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L2159) - Register an owner for a specified token identifier. Works when the *OwnerReverseLookupMode* is set to *Complete* +- [**revoke**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1138) - Revokes an account that was approved for an identified token transfer. The *OwnershipMode* must be set to *Transferable* +- [**set_approval_for_all**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1254) - Allows a spender to transfer all of the owner's tokens +- [**set_token_metadata**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1773) - Sets the metadata associated with a token identifier +- [**set_variables**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L496) - Allows the user to set any combination of variables simultaneously, defining which variables are mutable or immutable +- [**transfer**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1359) - Transfers tokens from the token owner to a specified account. The transfer will succeed if the caller is the token owner or an approved operator. The *OwnershipMode* must be set to *Transferable* +- [**updated_receipts**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L2111) - Allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own. Works when the *OwnerReverseLookupMode* is set to *Complete* + +There is also the [**migrate**](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1975) entrypoint, which was needed only for migrating a 1.0 version of the NFT contract to version 1.1. + +**IMPORTANT**: The following entrypoints return data using `runtime::ret`, which is useful mainly if the entrypoint caller is a contract: + +- `mint` (with *OwnerReverseLookupMode* set to *Complete*) +- `transfer` (with *OwnerReverseLookupMode* set to *TransfersOnly*) +- `balance_of` +- `is_approved_for_all` +- `owner_of` +- `metadata` + +## Installing the Contract + +Installing the enhanced NFT contract to global state requires using a [Deploy](https://docs.casper.network/developers/dapps/sending-deploys/). But before proceeding with the installation, verify the network state and the status of the account that will send the installation deploy. + +### Querying Global State + +This step queries information about the network state given the latest state root hash. You will also need the [IP address](https://docs.casper.network/developers/prerequisites/#acquire-node-address-from-network-peers) from a Testnet peer node. + +```bash +casper-client get-state-root-hash --node-address http://localhost:11101/rpc/ +``` + +### Querying the Account State + +Run the following command and supply the path to your public key in hexadecimal format to get the account hash if you don't have it already. + +```bash +casper-client account-address --public-key [PATH_TO_PUBLIC_KEY_HEX] +``` + +Use the command below to query the state of your account. + +```bash +casper-client query-global-state --node-address http:// \ +--state-root-hash [STATE_ROOT_HASH] \ +--key [ACCOUNT_HASH] +``` + +
+Expand for a sample query and response + +```bash +casper-client query-global-state --node-address http://localhost:11101/rpc/ \ +--state-root-hash 376b18e95312328f212f9966200fa40734e66118cbd34ace0a1ec14eacaea6e6 \ +--key account-hash-82729ae3b368bb2c45d23c05c872c446cbcf32b694f1d9efd3d1ea46cf227a11 +``` + +```json +{ + "jsonrpc": "2.0", + "id": -6733022256306802125, + "result": { + "api_version": "1.5.6", + "block_header": null, + "stored_value": { + "Account": { + "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "named_keys": [], + "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007", + "associated_keys": [ + { + "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "weight": 1 + } + ], + "action_thresholds": { + "deployment": 1, + "key_management": 1 + } + } + }, + "merkle_proof": "[32706 hex chars]" + } +} +``` + +
+ + +### Sending the Installation Deploy + +Below is an example of a `casper-client` command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state. + +Use the Testnet to understand the exact gas amount required for installation. Refer to the [note about gas prices](https://docs.casper.network/developers/cli/sending-deploys/#a-note-about-gas-price) to understand payment amounts and gas price adjustments. + +- `casper-client put-deploy -n http://localhost:11101/rpc/ --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm` + +1. `--session-arg "collection_name:string='CEP-78-collection'"` + + The name of the NFT collection as a string. In this instance, "CEP-78-collection". + +2. `--session-arg "collection_symbol:string='CEP78'"` + + The symbol representing the NFT collection as a string. In this instance, "CEP78". + +3. `--session-arg "total_token_supply:u64='100'"` + + The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution. + +4. `--session-arg "ownership_mode:u8='2'"` + + The ownership mode for this contract. In this instance, the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another. + +5. `--session-arg "nft_kind:u8='1'"` + + The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection. + +6. `--session-arg "nft_metadata_kind:u8='0'"` + + The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata. + +7. `--session-arg "json_schema:string=''"` + + An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom-validated modality would require passing through a valid JSON schema for your custom metadata. + +8. `--session-arg "identifier_mode:u8='0'"` + + The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash. + +9. `--session-arg "metadata_mutability:u8='0'"` + + A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata. + +The session arguments match the available [modalities](../../modalities.md). + + +
+Expand for a sample query and response + +```bash +casper-client put-deploy --node-address http://localhost:11101/rpc/ \ +--chain-name "casper-net-1" \ +--payment-amount 500000000000 \ +--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \ +--session-arg "collection_name:string='CEP-78-collection'" \ +--session-arg "collection_symbol:string='CEP78'" \ +--session-arg "total_token_supply:u64='100'" \ +--session-arg "ownership_mode:u8='2'" \ +--session-arg "nft_kind:u8='1'" \ +--session-arg "nft_metadata_kind:u8='0'" \ +--session-arg "json_schema:string='nft-schema'" \ +--session-arg "identifier_mode:u8='0'" \ +--session-arg "metadata_mutability:u8='0'" +``` + +This command will output the `deploy_hash`, which can be used in the next step to verify the installation. + +```bash +{ + "jsonrpc": "2.0", + "id": 3104428017957320684, + "result": { + "api_version": "1.0.0", + "deploy_hash": "2b084bdccbaaae2b9c6e4de2f5a6cdf06c72f0d02eaeb7d681a29ebdbe3c92b7" + } +} +``` + +
+ + +### Verifying the Installation + +Verify the sent deploy using the `get-deploy` command. + +```bash +casper-client get-deploy --node-address http://localhost:11101/rpc/ [DEPLOY_HASH] +``` + +
+Expand for sample deploy details + +```json +{ + "jsonrpc": "2.0", + "id": -7282936875867676694, + "result": { + "api_version": "1.5.6", + "deploy": { + "hash": "1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe", + "header": { + "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "timestamp": "2024-02-29T18:28:16.104Z", + "ttl": "30m", + "gas_price": 1, + "body_hash": "90866126c3dbb9a27f672307102bf651663934ee34715d46f9f02caa70226743", + "dependencies": [], + "chain_name": "casper-test" + }, + "payment": { + "ModuleBytes": { + "module_bytes": "", + "args": [ + [ + "amount", + { + "cl_type": "U512", + "bytes": "050088526a74", + "parsed": "500000000000" + } + ] + ] + } + }, + "session": { + "ModuleBytes": { + "module_bytes": "[621680 hex chars]", + "args": [ + [ + "collection_name", + { + "cl_type": "String", + "bytes": "120000004345502d37382d636f6c6c656374696f6e32", + "parsed": "CEP-78-collection" + } + ], + [ + "collection_symbol", + { + "cl_type": "String", + "bytes": "050000004345503738", + "parsed": "CEP78" + } + ], + [ + "total_token_supply", + { + "cl_type": "U64", + "bytes": "6400000000000000", + "parsed": 100 + } + ], + [ + "ownership_mode", + { + "cl_type": "U8", + "bytes": "02", + "parsed": 2 + } + ], + [ + "nft_kind", + { + "cl_type": "U8", + "bytes": "01", + "parsed": 1 + } + ], + [ + "nft_metadata_kind", + { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + ], + [ + "json_schema", + { + "cl_type": "String", + "bytes": "0a0000006e66742d736368656d61", + "parsed": "nft-schema" + } + ], + [ + "identifier_mode", + { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + ], + [ + "metadata_mutability", + { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + ] + ] + } + }, + "approvals": [ + { + "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "signature": "01f866dd88fd179fd214262d0451a92be2673e6d4095eb79beef9e5b8bbbc18862e76c3085dcb1b1ae669a185cb80d94c5084325913b8118338645952bb5ee2200" + } + ] + }, + "execution_results": [ + { + "block_hash": "dca9ff6e9ad7baeead715504dee098069f30dbb9975730be3d3926ab1c58f332", + "result": { + "Success": { + "effect": { + "operations": [], + "transforms": [ + { + "key": "account-hash-6174cf2e6f8fed1715c9a3bace9c50bfe572eecb763b0ed3f644532616452008", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", + "transform": "Identity" + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": "Identity" + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", + "transform": { + "WriteCLValue": { + "cl_type": "U512", + "bytes": "05c2d627778f", + "parsed": "616179422914" + } + } + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": { + "AddUInt512": "500000000000" + } + }, + { + "key": "uref-e42cd3ae8b4bd60306a72f0f4e9faa4e114e2e2cce5db03bfdd109a8db888e14-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30", + "transform": "WriteContractPackage" + }, + { + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "transform": { + "AddKeys": [ + { + "name": "cep78_contract_package_CEP-78-collection", + "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30" + } + ] + } + }, + { + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "transform": { + "AddKeys": [ + { + "name": "cep78_contract_package_access_CEP-78-collection", + "key": "uref-e42cd3ae8b4bd60306a72f0f4e9faa4e114e2e2cce5db03bfdd109a8db888e14-007" + } + ] + } + }, + { + "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30", + "transform": "Identity" + }, + { + "key": "hash-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b", + "transform": "WriteContractWasm" + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": "WriteContract" + }, + { + "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30", + "transform": "WriteContractPackage" + }, + { + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "transform": { + "AddKeys": [ + { + "name": "cep78_contract_hash_CEP-78-collection", + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796" + } + ] + } + }, + { + "key": "uref-0545c60c0a55e4d8a10fe0c3b2d356150b082e2243b6795b34f67643e4ca13d0-000", + "transform": { + "WriteCLValue": { + "cl_type": "U32", + "bytes": "01000000", + "parsed": 1 + } + } + }, + { + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "transform": { + "AddKeys": [ + { + "name": "cep78_contract_version_CEP-78-collection", + "key": "uref-0545c60c0a55e4d8a10fe0c3b2d356150b082e2243b6795b34f67643e4ca13d0-007" + } + ] + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": "Identity" + }, + { + "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30", + "transform": "Identity" + }, + { + "key": "hash-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b", + "transform": "Identity" + }, + { + "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-000", + "transform": { + "WriteCLValue": { + "cl_type": "String", + "bytes": "120000004345502d37382d636f6c6c656374696f6e32", + "parsed": "CEP-78-collection" + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "collection_name", + "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-007" + } + ] + } + }, + { + "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-000", + "transform": { + "WriteCLValue": { + "cl_type": "String", + "bytes": "050000004345503738", + "parsed": "CEP78" + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "collection_symbol", + "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-007" + } + ] + } + }, + { + "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-000", + "transform": { + "WriteCLValue": { + "cl_type": "U64", + "bytes": "6400000000000000", + "parsed": 100 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "total_token_supply", + "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-007" + } + ] + } + }, + { + "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "02", + "parsed": 2 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "ownership_mode", + "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-007" + } + ] + } + }, + { + "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "01", + "parsed": 1 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "nft_kind", + "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-007" + } + ] + } + }, + { + "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-000", + "transform": { + "WriteCLValue": { + "cl_type": "String", + "bytes": "0a0000006e66742d736368656d61", + "parsed": "nft-schema" + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "json_schema", + "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-007" + } + ] + } + }, + { + "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "minting_mode", + "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-007" + } + ] + } + }, + { + "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "02", + "parsed": 2 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "holder_mode", + "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-007" + } + ] + } + }, + { + "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "whitelist_mode", + "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-007" + } + ] + } + }, + { + "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-000", + "transform": { + "WriteCLValue": { + "cl_type": "String", + "bytes": "1800000063657037385f4345502d37382d636f6c6c656374696f6e32", + "parsed": "cep78_CEP-78-collection" + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "receipt_name", + "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-007" + } + ] + } + }, + { + "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-000", + "transform": { + "WriteCLValue": { + "cl_type": "String", + "bytes": "[170 hex chars]", + "parsed": "contract-package-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30" + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "cep78_CEP-78-collection", + "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-007" + } + ] + } + }, + { + "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "nft_metadata_kind", + "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-007" + } + ] + } + }, + { + "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-000", + "transform": { + "WriteCLValue": { + "cl_type": { + "Map": { + "key": "U8", + "value": "U8" + } + }, + "bytes": "010000000000", + "parsed": [ + { + "key": 0, + "value": 0 + } + ] + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "nft_metadata_kinds", + "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-007" + } + ] + } + }, + { + "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "identifier_mode", + "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-007" + } + ] + } + }, + { + "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "metadata_mutability", + "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-007" + } + ] + } + }, + { + "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "burn_mode", + "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-007" + } + ] + } + }, + { + "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-000", + "transform": { + "WriteCLValue": { + "cl_type": "Bool", + "bytes": "00", + "parsed": false + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "operator_burn_mode", + "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-007" + } + ] + } + }, + { + "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "events_mode", + "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-007" + } + ] + } + }, + { + "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-000", + "transform": { + "WriteCLValue": { + "cl_type": "Bool", + "bytes": "01", + "parsed": true + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "allow_minting", + "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-007" + } + ] + } + }, + { + "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-000", + "transform": { + "WriteCLValue": { + "cl_type": "U64", + "bytes": "0000000000000000", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "number_of_minted_tokens", + "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-007" + } + ] + } + }, + { + "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "token_owners", + "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-007" + } + ] + } + }, + { + "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "token_issuers", + "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-007" + } + ] + } + }, + { + "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "approved", + "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-007" + } + ] + } + }, + { + "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "operators", + "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-007" + } + ] + } + }, + { + "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "burnt_tokens", + "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-007" + } + ] + } + }, + { + "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "balances", + "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-007" + } + ] + } + }, + { + "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "metadata_custom_validated", + "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-007" + } + ] + } + }, + { + "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "metadata_cep78", + "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-007" + } + ] + } + }, + { + "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "metadata_nft721", + "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-007" + } + ] + } + }, + { + "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "metadata_raw", + "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-007" + } + ] + } + }, + { + "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "hash_by_index", + "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-007" + } + ] + } + }, + { + "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "index_by_hash", + "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-007" + } + ] + } + }, + { + "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "page_table", + "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-007" + } + ] + } + }, + { + "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-000", + "transform": { + "WriteCLValue": { + "cl_type": "Unit", + "bytes": "", + "parsed": null + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "acl_whitelist", + "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-007" + } + ] + } + }, + { + "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-000", + "transform": { + "WriteCLValue": { + "cl_type": "Bool", + "bytes": "00", + "parsed": false + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "acl_package_mode", + "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-007" + } + ] + } + }, + { + "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-000", + "transform": { + "WriteCLValue": { + "cl_type": "Bool", + "bytes": "00", + "parsed": false + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "package_operator_mode", + "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-007" + } + ] + } + }, + { + "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-000", + "transform": { + "WriteCLValue": { + "cl_type": "U8", + "bytes": "00", + "parsed": 0 + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "reporting_mode", + "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-007" + } + ] + } + }, + { + "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-000", + "transform": { + "WriteCLValue": { + "cl_type": "Bool", + "bytes": "00", + "parsed": false + } + } + }, + { + "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796", + "transform": { + "AddKeys": [ + { + "name": "rlo_mflag", + "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-007" + } + ] + } + }, + { + "key": "deploy-1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe", + "transform": { + "WriteDeployInfo": { + "deploy_hash": "1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe", + "transfers": [], + "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007", + "gas": "443359442322" + } + } + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": "Identity" + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", + "transform": "Identity" + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": { + "WriteCLValue": { + "cl_type": "U512", + "bytes": "055bdf0a5c67", + "parsed": "443925847899" + } + } + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", + "transform": { + "AddUInt512": "56074152101" + } + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": "Identity" + }, + { + "key": "balance-dcf5abbbe00715e9a05f7449109b1d297cb1584560ec4f3f5a86401452e40d85", + "transform": "Identity" + }, + { + "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", + "transform": { + "WriteCLValue": { + "cl_type": "U512", + "bytes": "00", + "parsed": "0" + } + } + }, + { + "key": "balance-dcf5abbbe00715e9a05f7449109b1d297cb1584560ec4f3f5a86401452e40d85", + "transform": { + "AddUInt512": "443925847899" + } + } + ] + }, + "transfers": [], + "cost": "443359442322" + } + } + } + ] + } +} +``` + +
+ +## Next Steps + +- Learn to [Query](./querying-NFTs.md) the NFT contract +- Learn to [Mint, Transfer, and Burn](./interacting-with-NFTs.md) NFT tokens diff --git a/docs/tutorials/getting-started/interacting-with-NFTs.md b/docs/tutorials/getting-started/interacting-with-NFTs.md new file mode 100644 index 00000000..28805dbe --- /dev/null +++ b/docs/tutorials/getting-started/interacting-with-NFTs.md @@ -0,0 +1,350 @@ +# Interacting with the NFT Contract using the Rust Casper Client + +This document describes interacting with NFTs on a Casper network using the Rust command-line client. + + +## Prerequisites + +- Install the contract using the [Quickstart](./quickstart-guide.md) or the [Full Installation](./full-installation-tutorial.md) tutorials +- Learn to [Query NFT Contracts](./querying-NFTs.md) and save the various hashes and URefs required throughout this document + + +## Table of Contents + +1. [Directly Invoking Entrypoints](#directly-invoking-entrypoints) + +2. [Minting NFTs](#minting-nfts) + +3. [Transferring NFTs](#transferring-nfts) + +4. [Checking Balances](#checking-balances) + +5. [Approving an Account](#approving-an-account) + +6. [Burning NFTs](#burning-nfts) + +7. [Next Steps](#next-steps) + + +## Directly Invoking Entrypoints + +With the release of CEP-78 version 1.1, users interacting with a CEP-78 contract that does not use `ReverseLookupMode` should opt out of using the client Wasm files provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost than using the provided client Wasm to invoke the entrypoint. + +You may invoke the `mint`, `transfer`, or `burn` entrypoints directly through either the contract package hash or the contract hash directly. + +In the case of `mint`, fewer runtime arguments must be provided, thereby reducing the total gas cost of minting an NFT. + +
+Example `mint` using the stored package hash + +```bash +casper-client put-deploy --node-address http://localhost:11101/rpc/ \ +--chain-name "casper-net-1” \ +--payment-amount 5000000000 \ +--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30 \ +--session-entry-point "mint" \ +--session-arg "token_owner:key='account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'" \ +--session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'" +``` + +
+ +
+Example `transfer` using the stored contract hash + +Based on the identifier mode for the given contract instance, either the `token_id` runtime argument must be passed in or, in the case of the hash identifier mode, the `token_hash` runtime argument. + +```bash +casper-client put-deploy --node-address http://localhost:11101/rpc/ \ +--chain-name "casper-net-1” \ +--payment-amount 5000000000 \ +--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \ +--session-entry-point "transfer" \ +--session-arg "source_key:key='account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'" \ +--session-arg "target_key:key='account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34'" \ +--session-arg "token_id:u64='0'" +``` + +
+ + +## Minting NFTs + +Below is an example of a `casper-client` command that uses the `mint` entrypoint of the contract to mint an NFT for the user associated with `node-1` in an [NCTL environment](https://docs.casper.network/developers/dapps/nctl-test/). + +- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "mint"` + +1. `--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30` + + The package hash of the previously installed CEP-78 NFT contract from which we will be minting. + +2. `--session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"` + + The collection name of the NFT to be minted. + +3. `--session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'"` + + Metadata describing the NFT to be minted, passed in as a `string`. + +**Note**: If the `identifier_mode` was set to hash (1) during installation, the `token_hash` runtime argument needs to be specified during minting. Since you already know the NFT's identifier, you can easily query the NFT's `meta_data`, which is a very useful feature. This example uses an ordinal (0) `identifier_mode`. + +
+Casper client command without comments + +```bash +casper-client put-deploy --node-address http://localhost:11101/rpc/ \ +--chain-name "casper-net-1” \ +--payment-amount 5000000000 \ +--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-entry-point "mint" \ +--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30 \ +--session-arg "token_owner:key='account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'" \ +--session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'" +``` + +
+ + +### Minting NFTs using Wasm + +This example invokes the `mint_call.wasm` session code provided in the `client` folder. + +- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm` + +1. `--session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'"` + + The contract hash of the previously installed CEP-78 NFT contract from which we will be minting. + +2. `--session-arg "collection_name:string='cep78_'"` + + The collection name of the previously installed CEP-78 NFT contract from which we will be minting. + +3. `--session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"` + + The collection name of the NFT to be minted. + +4. `--session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'"` + + Metadata describing the NFT to be minted, passed in as a `string`. + + +
+Casper client command without comments + +```bash +casper-client put-deploy --node-address http://localhost:11101/rpc/ \ +--chain-name "casper-net-1” \ +--payment-amount 5000000000 \ +--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \ +--session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'" \ +--session-arg "collection_name:string='cep78_'" \ +--session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ +--session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'" +``` + +
+ + +## Transferring NFTs + +Below is an example of a `casper-client` command that uses the `transfer` entrypoint to transfer ownership of an NFT from one user to another. + +- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "transfer"` + +1. `--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'"` + + The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred. + +2. `--session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"` + + The account hash of the user that currently owns the NFT and wishes to transfer it. + +3. `--session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'"` + + The account hash of the user that will receive the NFT. + +4. `--session-arg "is_hash_identifier_mode:bool='false'"` + + The argument that the hash identifier mode is ordinal, thereby requiring a `token_id` rather than a `token_hash`. + +5. `--session-arg "token_id:u64='0'"` + + The `token_id` of the NFT to be transferred. + +
+Casper client command without comments + +```bash +casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ +--payment-amount 5000000000 \ +-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-entry-point "transfer" \ +--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \ +--session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ +--session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \ +--session-arg "is_hash_identifier_mode:bool='false'" \ +--session-arg "token_id:u64='0'" +``` + +
+ +This command will return a deploy hash that you can query using `casper-client get-deploy`. Querying the deploy allows you to verify execution success, but you will need to use the `balance_of` entrypoint to verify the account's balance as shown [below](#checking-the-balance). + + +### Transferring NFTs using Wasm + +This example uses the `transfer_call.wasm` session code to transfer ownership of an NFT from one user to another. + +- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm` + +1. `--session-arg "nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'"` + + The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred. + +2. `--session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"` + + The account hash of the user that currently owns the NFT and wishes to transfer it. + +3. `--session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'"` + + The account hash of the user that will receive the NFT. + +4. `--session-arg "is_hash_identifier_mode:bool='false'"` + + Argument that the hash identifier mode is ordinal, thereby requiring a `token_id` rather than a `token_hash`. + +5. `--session-arg "token_id:u64='0'"` + + The `token_id` of the NFT to be transferred. + +
+Casper client command without comments + +```bash +casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ +--payment-amount 5000000000 \ +-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \ +--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \ +--session-arg "nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'" \ +--session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ +--session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \ +--session-arg "is_hash_identifier_mode:bool='false'" \ +--session-arg "token_id:u64='0'" +``` + +
+ + +## Checking Balances + +To check an account's balance, get the latest state root hash and query the `balances` dictionary given the NFT contract hash and the owner's account hash without the "account-hash-" prefix, as shown below. + +- `casper-client get-dictionary-item -n http://localhost:11101/rpc` + +1. `--state-root-hash f22e8ecfb3d2700d5f902c83da456c32f130b73d0d35037fe89b2d4b4933673f` + + The latest state root hash. + +2. `--contract-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796` + + The NFT contract hash. + +3. `--dictionary-name "balances"` + + The dictionary tracking the number of tokens for each account hash. + +4. `--dictionary-item-key "0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34"` + + The account hash of the user whose token balance we are checking without the `account-hash-` prefix. + +
+Casper client commands without comments + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client get-dictionary-item -n http://localhost:11101/rpc/ \ +--state-root-hash f22e8ecfb3d2700d5f902c83da456c32f130b73d0d35037fe89b2d4b4933673f \ +--contract-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \ +--dictionary-name "balances" \ +--dictionary-item-key "0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34" +``` + +
+ + +## Approving an Account + +The Casper NFT contract features an `approve` entrypoint, allowing another account to manage a specific token. During contract installation, the `ownership_mode` must be set to 2, meaning `Transferable`. + +- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "approve"` + +1. `--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5` + + The contract hash of the previously installed CEP-78 NFT contract. + +2. `--session-arg "spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'"` + + The hash of the account receiving the approval. + +3. `--session-arg "token_id:u64='1'"` + + The token ID of the approved NFT. + + +
+Casper client command without comments + +```bash +casper-client put-deploy -n http://localhost:11101/rpc/ \ +--chain-name "casper-net-1" \ +--payment-amount 5000000000 \ +-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-entry-point "approve" \ +--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \ +--session-arg "spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \ +--session-arg "token_id:u64='1'" +``` + +
+ + +## Burning NFTs + +Below is an example of a `casper-client` command that uses the `burn` entrypoint to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone. + +- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem` + +1. `--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5` + + The session hash corresponding to the NFT's contract hash. + +2. `--session-entry-point "burn"` + + The entrypoint corresponding to the `burn` function. + +3. `--session-arg "token_id:u64='1'"` + + The token ID for the NFT to be burned. If the `identifier_mode` is not set to `Ordinal`, you must provide the `token_hash` instead. + +
+Casper client command without comments + +```bash +casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ +--payment-amount 5000000000 \ +-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \ +--session-entry-point "burn" \ +--session-arg "token_id:u64='1'" +``` + +
+ + +## Next Steps + +- [Testing Framework for CEP-78](./testing-NFTs.md) \ No newline at end of file diff --git a/docs/tutorials/getting-started/querying-NFTs.md b/docs/tutorials/getting-started/querying-NFTs.md new file mode 100644 index 00000000..18bf5a4d --- /dev/null +++ b/docs/tutorials/getting-started/querying-NFTs.md @@ -0,0 +1,548 @@ +# Querying NFT Contracts + +This document covers different commands to query and interact with an NFT (CEP-78) contract instance. + +## Prerequisites + +- Install the contract using the [Quickstart](./quickstart-guide.md) or the [Full Installation](./full-installation-tutorial.md) tutorials + +## Querying the Contract + +First, identify the contract hash by looking at the account that installed the contract. Under the account's named keys, you will see a named key for the contract hash, representing the stored contract. Copy this value and save it for future queries. + +
+Accessing the NFT Contract Hash +
+ +
+ +Next, query the contract details. + +- `casper-client query-global-state -n http://localhost:11101/rpc/` + +1. `--key [CONTRACT_HASH]` + + The contract hash, found within the `NamedKeys` of the account that sent the installing deploy. + +2. `--state-root-hash [STATE_ROOT_HASH]` + + The most up-to-date state root hash, which can be found by using the `get-state-root-hash` command in the Casper client. + +
+Expand to see the query and sample contract + + +```bash +casper-client query-global-state -n http://localhost:11101/rpc/ \ +--key hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \ +--state-root-hash 2a8cfc20d24b4bc629ea6d26cc820560a1baf3d4275079d5382242c9fa1e86fe +``` + +```json +{ + "jsonrpc": "2.0", + "id": -5355991397545050403, + "result": { + "api_version": "1.5.6", + "block_header": null, + "stored_value": { + "Contract": { + "contract_package_hash": "contract-package-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30", + "contract_wasm_hash": "contract-wasm-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b", + "named_keys": [ + { + "name": "acl_package_mode", + "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-007" + }, + { + "name": "acl_whitelist", + "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-007" + }, + { + "name": "allow_minting", + "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-007" + }, + { + "name": "approved", + "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-007" + }, + { + "name": "balances", + "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-007" + }, + { + "name": "burn_mode", + "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-007" + }, + { + "name": "burnt_tokens", + "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-007" + }, + { + "name": "cep78_CEP-78-collection2", + "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-007" + }, + { + "name": "collection_name", + "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-007" + }, + { + "name": "collection_symbol", + "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-007" + }, + { + "name": "events_mode", + "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-007" + }, + { + "name": "hash_by_index", + "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-007" + }, + { + "name": "holder_mode", + "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-007" + }, + { + "name": "identifier_mode", + "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-007" + }, + { + "name": "index_by_hash", + "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-007" + }, + { + "name": "installer", + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655" + }, + { + "name": "json_schema", + "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-007" + }, + { + "name": "metadata_cep78", + "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-007" + }, + { + "name": "metadata_custom_validated", + "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-007" + }, + { + "name": "metadata_mutability", + "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-007" + }, + { + "name": "metadata_nft721", + "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-007" + }, + { + "name": "metadata_raw", + "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-007" + }, + { + "name": "minting_mode", + "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-007" + }, + { + "name": "nft_kind", + "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-007" + }, + { + "name": "nft_metadata_kind", + "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-007" + }, + { + "name": "nft_metadata_kinds", + "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-007" + }, + { + "name": "number_of_minted_tokens", + "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-007" + }, + { + "name": "operator_burn_mode", + "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-007" + }, + { + "name": "operators", + "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-007" + }, + { + "name": "ownership_mode", + "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-007" + }, + { + "name": "package_operator_mode", + "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-007" + }, + { + "name": "page_table", + "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-007" + }, + { + "name": "receipt_name", + "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-007" + }, + { + "name": "reporting_mode", + "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-007" + }, + { + "name": "rlo_mflag", + "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-007" + }, + { + "name": "token_issuers", + "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-007" + }, + { + "name": "token_owners", + "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-007" + }, + { + "name": "total_token_supply", + "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-007" + }, + { + "name": "whitelist_mode", + "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-007" + } + ], + "entry_points": [ + { + "name": "approve", + "args": [ + { + "name": "spender", + "cl_type": "Key" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "balance_of", + "args": [ + { + "name": "token_owner", + "cl_type": "Key" + } + ], + "ret": "U64", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "burn", + "args": [], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "get_approved", + "args": [], + "ret": { + "Option": "Key" + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "init", + "args": [ + { + "name": "collection_name", + "cl_type": "String" + }, + { + "name": "collection_symbol", + "cl_type": "String" + }, + { + "name": "total_token_supply", + "cl_type": "U64" + }, + { + "name": "allow_minting", + "cl_type": "Bool" + }, + { + "name": "minting_mode", + "cl_type": "U8" + }, + { + "name": "ownership_mode", + "cl_type": "U8" + }, + { + "name": "nft_kind", + "cl_type": "U8" + }, + { + "name": "holder_mode", + "cl_type": "U8" + }, + { + "name": "whitelist_mode", + "cl_type": "U8" + }, + { + "name": "acl_whitelist", + "cl_type": { + "List": "Key" + } + }, + { + "name": "acl_package_mode", + "cl_type": "Bool" + }, + { + "name": "package_operator_mode", + "cl_type": "Bool" + }, + { + "name": "json_schema", + "cl_type": "String" + }, + { + "name": "receipt_name", + "cl_type": "String" + }, + { + "name": "identifier_mode", + "cl_type": "U8" + }, + { + "name": "burn_mode", + "cl_type": "U8" + }, + { + "name": "operator_burn_mode", + "cl_type": "Bool" + }, + { + "name": "nft_metadata_kind", + "cl_type": "U8" + }, + { + "name": "metadata_mutability", + "cl_type": "U8" + }, + { + "name": "owner_reverse_lookup_mode", + "cl_type": "U8" + }, + { + "name": "events_mode", + "cl_type": "U8" + }, + { + "name": "transfer_filter_contract", + "cl_type": { + "Option": "Key" + } + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "is_approved_for_all", + "args": [ + { + "name": "token_owner", + "cl_type": "Key" + }, + { + "name": "operator", + "cl_type": "Key" + } + ], + "ret": "Bool", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "metadata", + "args": [], + "ret": "String", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "migrate", + "args": [ + { + "name": "cep78_package_key", + "cl_type": "Any" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "mint", + "args": [ + { + "name": "token_owner", + "cl_type": "Key" + }, + { + "name": "token_meta_data", + "cl_type": "String" + } + ], + "ret": { + "Tuple3": [ + "String", + "Key", + "String" + ] + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "owner_of", + "args": [], + "ret": "Key", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "register_owner", + "args": [], + "ret": { + "Tuple2": [ + "String", + "URef" + ] + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "revoke", + "args": [], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "set_approval_for_all", + "args": [ + { + "name": "approve_all", + "cl_type": "Bool" + }, + { + "name": "operator", + "cl_type": "Key" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "set_token_metadata", + "args": [ + { + "name": "token_meta_data", + "cl_type": "String" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "set_variables", + "args": [ + { + "name": "allow_minting", + "cl_type": "Bool" + }, + { + "name": "contract_whitelist", + "cl_type": { + "List": { + "ByteArray": 32 + } + } + }, + { + "name": "acl_whitelist", + "cl_type": { + "List": "Key" + } + }, + { + "name": "acl_package_mode", + "cl_type": "Bool" + }, + { + "name": "package_operator_mode", + "cl_type": "Bool" + }, + { + "name": "operator_burn_mode", + "cl_type": "Bool" + } + ], + "ret": "Unit", + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "transfer", + "args": [ + { + "name": "source_key", + "cl_type": "Key" + }, + { + "name": "target_key", + "cl_type": "Key" + } + ], + "ret": { + "Tuple2": [ + "String", + "Key" + ] + }, + "access": "Public", + "entry_point_type": "Contract" + }, + { + "name": "updated_receipts", + "args": [], + "ret": { + "List": { + "Tuple2": [ + "String", + "Key" + ] + } + }, + "access": "Public", + "entry_point_type": "Contract" + } + ], + "protocol_version": "1.5.6" + } + }, + "merkle_proof": "[33244 hex chars]" + } +} +``` + +
+ +## Next Steps + +- Learn to [Mint, Transfer, and Burn](./interacting-with-NFTs.md) NFT tokens \ No newline at end of file diff --git a/docs/tutorials/getting-started/quickstart-guide.md b/docs/tutorials/getting-started/quickstart-guide.md new file mode 100644 index 00000000..0c3eebd8 --- /dev/null +++ b/docs/tutorials/getting-started/quickstart-guide.md @@ -0,0 +1,64 @@ +# Casper NFT Quick Start Guide + +This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the [Casper Testnet](https://testnet.cspr.live/). To execute transactions on a Casper network involving NFTs, you will need some CSPR tokens to pay for the transactions. The Testnet provides test tokens using a [faucet](https://docs.casper.network/users/testnet-faucet/). + +For greater detail into the creation and mechanics of the Casper NFT contract, see the complete [Casper NFT Tutorial](./full-installation-tutorial.md). + +## Prerequisites + +Before using this guide, ensure you meet the following requirements: + +- Set up the [development prerequisites](https://docs.casper.network/developers/prerequisites/), including the [Casper client](https://docs.casper.network/developers/prerequisites/#install-casper-client) +- Get a valid [node address](https://docs.casper.network/developers/prerequisites/#acquire-node-address-from-network-peers) from the network +- Know how to install a [smart contract](https://docs.casper.network/developers/cli/sending-deploys/) on a Casper network +- Hold enough CSPR tokens to pay for transactions + +## Setup + +Clone the Casper NFT (CEP-78) [contract repository](https://github.com/casper-ecosystem/cep-78-enhanced-nft/). + +```bash +git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft +``` + +Run the following commands to build the `contract.wasm` in the `contract/target/wasm32-unknown-unknown/release` directory and run the tests. + +```bash +make prepare +make test +``` + +The output of the command would end with the following message: + +```bash +test result: ok. 159 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.33s +``` + +## Installing the NFT Contract + +The following command will install a sample NFT contract on the Testnet: + +```bash +casper-client put-deploy --node-address http://localhost:11101/rpc/ \ +--chain-name "casper-net-1" \ +--payment-amount 5000000000 \ +--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ +--session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \ +--session-arg "collection_name:string='CEP-78-collection'" \ +--session-arg "collection_symbol:string='CEP78'" \ +--session-arg "total_token_supply:u64='100'" \ +--session-arg "ownership_mode:u8='2'" \ +--session-arg "nft_kind:u8='1'" \ +--session-arg "nft_metadata_kind:u8='0'" \ +--session-arg "json_schema:string='nft-schema'" \ +--session-arg "identifier_mode:u8='0'" \ +--session-arg "metadata_mutability:u8='0'" +``` + +## Next Steps + +Learn to query the contract, perform token transfers, set up approvals, and understand the testing framework. + +- [Query](./querying-NFTs.md) the NTF Contract +- Learn to [Mint, Transfer, and Burn](./interacting-with-NFTs.md) NFT tokens +- Review the [Tests](./testing-NFTs.md) \ No newline at end of file diff --git a/docs/tutorials/getting-started/testing-NFTs.md b/docs/tutorials/getting-started/testing-NFTs.md new file mode 100644 index 00000000..fe291c2c --- /dev/null +++ b/docs/tutorials/getting-started/testing-NFTs.md @@ -0,0 +1,25 @@ +# Testing NFT Contracts + +## Prerequisites + +- Install the contract using the [Quickstart](./quickstart-guide.md) or the [Full Installation](./full-installation-tutorial.md) tutorials + +## Framework Description + +The testing framework in this tutorial uses the [Casper engine test support](https://crates.io/crates/casper-engine-test-support) crate for testing the contract implementation against the Casper execution environment. + +The [tests](../../../tests/) folder contains over 150 tests covering a variety of scenarios, including contract installation, minting and burning tokens, sending transfers, upgrading the contract, and listening to events. + +For more details about the test framework and how each test is set up, visit the [Testing Smart Contracts](https://docs.casper.network/developers/writing-onchain-code/testing-contracts/) documentation page. + +## Running the Tests + +To build and run the tests, issue the following command in the project folder: + +```bash +make test +``` + +The project contains a [Makefile](../../../Makefile), which is a custom build script that compiles the contract before running tests in _release_ mode. Then, the script copies the `contract.wasm` file to the corresponding version folder in the `tests/wasm` directory. In practice, you only need to run the `make test` command during development without building the contract separately. + +This example uses `bash`. If you use a Rust IDE, you must configure it to run the tests. \ No newline at end of file diff --git a/tutorials/standard-migration-tutorial.md b/docs/tutorials/standard-migration-tutorial.md similarity index 84% rename from tutorials/standard-migration-tutorial.md rename to docs/tutorials/standard-migration-tutorial.md index 6a52c94b..43861807 100644 --- a/tutorials/standard-migration-tutorial.md +++ b/docs/tutorials/standard-migration-tutorial.md @@ -8,11 +8,11 @@ This tutorial uses the Casper command-line client to upgrade *and* migrate from - Your v1.0.0 NFT contract instance uses the contract package hash and contract package access URef created during installation in a **standard way**, without using other NamedKeys to manage the contract package. - You have the v1.0.0 contract package hash stored under the `nft_contract_package` NamedKey in the account that installed the contract. - You have the v1.0.0 contract package access URef stored under the `nft_contract_package_access` NamedKey in the account that installed the contract. -- You understand what is new in [Version 1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1) of the CEP-78 Enhanced NFT Standard. +- You understand what is new in [Version 1.1.0](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.0) of the CEP-78 Enhanced NFT Standard. ## Upgrading and Migrating Terminology -An [upgrade](https://docs.casper.network/developers/writing-onchain-code/upgrading-contracts/) is the usual manner to release newer versions of a contract inside a contract package. When users install v1.1.* of a CEP-78 contract, they perform an upgrade and a data migration to a new [page system](../docs/reverse-lookup.md#the-cep-78-page-system) tracking token ownership. The [OwnerReverseLookupMode](../docs/modalities.md#ownerreverselookupmode) modality introduced in version 1.1.0 allows users to list NFTs by owner. The [README](../README.md) states: +An [upgrade](https://docs.casperlabs.io/dapp-dev-guide/writing-contracts/upgrading-contracts/) is the usual manner to release newer versions of a contract inside a contract package. When users install v1.1.* of a CEP-78 contract, they perform an upgrade and a data migration to a new [page system](../reverse-lookup.md#the-cep-78-page-system) tracking token ownership. The [OwnerReverseLookupMode](../modalities.md#ownerreverselookupmode) modality introduced in version 1.1.0 allows users to list NFTs by owner. The [README](../README.md) states: ``` If you are upgrading a contract from CEP-78 version 1.0 to 1.1, `OwnerReverseLookupMode` will be set to `Complete`, as this was the standard behavior of CEP-78 1.0. In addition to being set to `Complete`, existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration. @@ -28,7 +28,7 @@ The `cep-78-wasm` folder contains the `contract.wasm` to send to the network to ### Standard NamedKeys before Migration -The standard migration path assumes that the contract uses the NamedKey entries created during the v1.0.0 installation without any modifications. See the example below as well as the [NamedKeyConvention](../docs/modalities.md#namedkeyconventionmode) modality. +The standard migration path assumes that the contract uses the NamedKey entries created during the v1.0.0 installation without any modifications. See the example below as well as the [NamedKeyConvention](../modalities.md#namedkeyconventionmode) modality. | NamedKey Pre-Migration | Explanation | |-------------|-------------| @@ -45,8 +45,8 @@ The standard migration path assumes that the contract uses the NamedKey entries When upgrading using the `casper-client`, you must provide two runtime arguments: -- `named_key_convention`: The [NamedKeyConvention](../docs/modalities.md#namedkeyconventionmode) runtime argument as a u8 value equal to 1: `--session-arg "named_key_convention:u8='1'"`. See the [ARG_NAMED_KEY_CONVENTION](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L1991). -- `collection_name`: The collection name specified when the contract was [installed](../docs/using-casper-client.md#installing-the-contract) using the `collection_name` option. See the [contract code](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L93) for details.  +- `named_key_convention`: The [NamedKeyConvention](../modalities.md#namedkeyconventionmode) runtime argument as a u8 value equal to 1: `--session-arg "named_key_convention:u8='1'"`. See the [ARG_NAMED_KEY_CONVENTION](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L1991). +- `collection_name`: The collection name specified when the contract was [installed](./getting-started/full-installation-tutorial.md) using the `collection_name` option. See the [contract code](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/408db77c3b9ca22752c7f877ea99a01dfca03a7b/contract/src/main.rs#L93) for details.  Here is the `casper-client` command to upgrade and migrate to version 1.1.1 of the NFT collection specified: @@ -67,7 +67,7 @@ Here is the full list of required arguments: - `secret-key`: The file name containing the secret key of the account paying for the deploy. - `payment-amount`: The payment for the deploy in motes. - `session-path`: The path to the compiled Wasm on your computer. When using the [cep-78-wasm.tar.gz](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/download/v1.1.1/cep-78-wasm.tar.gz) provided, this would be the path to the `contract.wasm` file. -- `named_key_convention`: Argument that specifies the use of the `V_1_0_standard` [NamedKeyConvention](../docs/modalities.md#namedkeyconventionmode). +- `named_key_convention`: Argument that specifies the use of the `V_1_0_standard` [NamedKeyConvention](../modalities.md#namedkeyconventionmode). - `collection_name`: Argument that specifies the collection name as a String. The command returns the deploy hash that you can use to verify whether or not the deploy succeeded. @@ -86,7 +86,7 @@ The following is an example of upgrading and migrating to version 1.1.1 of a pre ```bash casper-client put-deploy \ ---node-addres http://65.21.235.219:7777 \ +--node-addres https://rpc.testnet.casperlabs.io/ \ --chain-name "casper-test" \ --secret-key ~/KEYS/secret_key.pem \ --payment-amount 300000000000 \ diff --git a/tutorials/token-ownership-tutorial.md b/docs/tutorials/token-ownership-tutorial.md similarity index 90% rename from tutorials/token-ownership-tutorial.md rename to docs/tutorials/token-ownership-tutorial.md index 2585aaeb..9aa8c921 100644 --- a/tutorials/token-ownership-tutorial.md +++ b/docs/tutorials/token-ownership-tutorial.md @@ -1,6 +1,6 @@ # Token Ownership in Casper NFT Contracts (Release v1.1.1) -This tutorial demonstrates how to check token ownership in CEP-78 NFT contracts, starting with version [v1.1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1). For this tutorial, the `OwnerReverseLookupMode` modality must be set to `Complete` as described [here](../docs/modalities.md#ownerreverselookupmode). +This tutorial demonstrates how to check token ownership in CEP-78 NFT contracts, starting with version [v1.1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1). For this tutorial, the `OwnerReverseLookupMode` modality must be set to `Complete` as described [here](../modalities.md#ownerreverselookupmode). As someone interacting with an NFT contract, you might want to answer the following questions: @@ -9,12 +9,12 @@ As someone interacting with an NFT contract, you might want to answer the follow You might be an account user or owner of a contract that interacts with the NFT contract. -The first method to answer these questions is an [account-centric approach](./token-ownership-tutorial.md#method-1---querying-the-account), in which you trust the account owner and the information stored in the account's NamedKeys. This account could be an account you own or someone else owns. This method is less secure and needs to be based on trust. To apply this method, proceed according to the following steps: +The first method to answer these questions is an [account-centric approach](#querying-the-account), in which you trust the account owner and the information stored in the account's NamedKeys. This account could be an account you own or someone else owns. This method is less secure and needs to be based on trust. To apply this method, proceed according to the following steps: - Look for NamedKeys in this format: "cep78_*_m_1000_p_#". - Query each "cep78_*_m_1000_p_#" dictionary using the `casper-client get-dictionary-item` and the `dictionary-address`. -The second method is a [contract-centric approach](./token-ownership-tutorial.md#method-2---querying-the-contract), in which you query the NFT contract. This method is more secure than the first approach and can be used when you need to verify or cannot trust an account's NamedKeys. To apply this method, follow these steps: +The second method is a [contract-centric approach](#querying-the-contract), in which you query the NFT contract. This method is more secure than the first approach and can be used when you need to verify or cannot trust an account's NamedKeys. To apply this method, follow these steps: - Query the "page_table" dictionary from the CEP-78 contract using its seed URef and the account hash (without the "account-hash-" prefix). - Then, query each page dictionary given its seed URef and the account hash (again, without the "account-hash-" prefix). @@ -27,10 +27,10 @@ The tutorial presents sample accounts, contracts, and NamedKeys to explain, by e ## Prerequisites -- You have installed or upgraded to a CEP-78 contract that uses release v1.1.1, and the `OwnerReverseLookupMode` modality is set to `Complete` as described [here](../docs/modalities.md#ownerreverselookupmode). +- You have installed or upgraded to a CEP-78 contract that uses release v1.1.1, and the `OwnerReverseLookupMode` modality is set to `Complete` as described [here](../modalities.md#ownerreverselookupmode). - The contract has minted one or more tokens, and you have access to the account or the contract that owns these tokens. - You have experience with the [Casper CEP-78 NFT Standard](https://github.com/casper-ecosystem/cep-78-enhanced-nft/) and the Casper command-line client and know how to interact with a Casper network. -- You understand the [Owner Reverse Lookup Functionality](../docs/reverse-lookup.md) and [CEP-78 Page System](../docs/reverse-lookup.md#the-cep-78-page-system) introduced in [Version 1.1](https://github.com/casper-ecosystem/cep-78-enhanced-nft/#new-in-version-11) of the CEP-78 Enhanced NFT Standard. +- You understand the [Owner Reverse Lookup Functionality](https://github.com/casper-ecosystem/cep-78-enhanced-nft/#owner-reverse-lookup-functionality) and [CEP-78 Page System](../docs/reverse-lookup.md#the-cep-78-page-system) introduced in [Version 1.1.0](https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.0) of the CEP-78 Enhanced NFT Standard. ## Method 1 - Querying the Account @@ -239,7 +239,7 @@ casper-client get-dictionary-item \ } ``` -Notice that the output is the same as what was displayed when using the first method; the dictionary address is "dictionary-eb837c4c92199e66619e163271a7e487704b5be7b103e785ed5b262f36ab6f50". Therefore, to understand the output, follow the [Tokens Identified by Token ID](./token-ownership-tutorial.md#tokens-identified-by-token-id) and [Tokens Identified by Hash](./token-ownership-tutorial.md#tokens-identified-by-hash) sections. +Notice that the output is the same as what was displayed when using the first method; the dictionary address is "dictionary-eb837c4c92199e66619e163271a7e487704b5be7b103e785ed5b262f36ab6f50". Therefore, to understand the output, follow the [Tokens Identified by Token ID](tokens-identified-by-token-id) and [Tokens Identified by Hash](tokens-identified-by-hash) sections. ## Frequently Asked Questions diff --git a/docs/using-casper-client.md b/docs/using-casper-client.md deleted file mode 100644 index b25784dd..00000000 --- a/docs/using-casper-client.md +++ /dev/null @@ -1,237 +0,0 @@ -# Installing and Interacting with the Contract using the Rust Casper Client - -This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of `1.63.0`. - -Information on the modalities used throughout this installation process can be found in the [modalities documentation](modalities.md). - -## Table of Contents - -1. [Installing the Contract](#installing-the-contract) - -2. [Directly Invoking Entrypoints](#directly-invoking-entrypoints) - -3. [Minting an NFT](#minting-an-nft) - -4. [Transferring NFTs Between Users](#transferring-nfts-between-users) - -5. [Burning an NFT](#burning-an-nft) - -## Installing the Contract - -Installing the enhanced NFT contract to global state requires the use of a [Deploy](https://docs.casper.network/developers/cli/sending-deploys/). In this case, the session code can be compiled to Wasm by running the `make build-contract` command provided in the Makefile at the top level. The Wasm will be found in the `contract/target/wasm32-unknown-unknown/release` directory as `contract.wasm`. - -Below is an example of a `casper-client` command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state. - -- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm` - -1. `--session-arg "collection_name:string='CEP-78-collection'"` - - The name of the NFT collection as a string. In this instance, "CEP-78-collection". - -2. `--session-arg "collection_symbol:string='CEP78'"` - - The symbol representing the NFT collection as a string. In this instance, "CEP78". - -3. `--session-arg "total_token_supply:u64='100'"` - - The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution. - -4. `--session-arg "ownership_mode:u8='2'"` - - The ownership mode for this contract. In this instance the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another. - -5. `--session-arg "nft_kind:u8='1'"` - - The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection. - -6. `--session-arg "nft_metadata_kind:u8='0'"` - - The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata. - -7. `--session-arg "json_schema:string=''"` - - An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom validated modality would require passing through a valid JSON schema for your custom metadata. - -8. `--session-arg "identifier_mode:u8='0'"` - - The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash. - -9. `--session-arg "metadata_mutability:u8='0'"` - - A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata. - -The session arguments match the available modalities as listed in this [README](https://github.com/casper-ecosystem/cep-78-enhanced-nft). - -
-Casper client command without comments - -```bash -casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm \ ---session-arg "collection_name:string='CEP-78-collection'" \ ---session-arg "collection_symbol:string='CEP78'" \ ---session-arg "total_token_supply:u64='100'" \ ---session-arg "ownership_mode:u8='2'" \ ---session-arg "nft_kind:u8='1'" \ ---session-arg "nft_metadata_kind:u8='0'" \ ---session-arg "json_schema:string=''" \ ---session-arg "identifier_mode:u8='0'" \ ---session-arg "metadata_mutability:u8='0'" -``` - -
- -## Directly Invoking Entrypoints - -With the release of CEP-78 version 1.1, users that are interacting with a CEP-78 contract that does not use `ReverseLookupMode` should opt out of using the client Wasms provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost compared against using the provided client Wasm to invoke the entrypoint. - -You may invoke the `mint`, `transfer` or `burn` entrypoints directly through either the contract package hash or the contract hash directly. - -Specifically in the case of `mint`, there are fewer runtime arguments that must be provided, thereby reducing the total gas cost of minting an NFT. - -
-Example Mint using StoredVersionByHash - -```bash - -casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ --payment-amount 7500000000 \ -k ~/secret_key.pem \ ---session-package-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \ ---session-entry-point "mint" \ ---session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ ---session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'" - -``` - -
- -
-Example Transfer using StoredContractByHash - -Based on the identifier mode for the given contract instance, either the `token_id` runtime argument must be passed in or in the case of the hash identifier mode, the `token_hash` runtime argument. - -```bash - -casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ --payment-amount 7500000000 \ -k ~/secret_key.pem \ ---session-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \ ---session-entry-point "transfer" \ ---session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ ---session-arg "target_key:key='account-hash-b4782e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \ ---session-arg "token_id:u64='0'" - -``` - -
- -## Minting an NFT - -Below is an example of a `casper-client` command that uses the `mint` function of the contract to mint an NFT for the user associated with `node-1` in an [NCTL environment](https://docs.casper.network/developers/dapps/nctl-test/). - -- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm` - -1. `--session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'"` - - The contract hash of the previously installed CEP-78 NFT contract from which we will be minting. - -2. `--session-arg "collection_name:string='cep78_'"` - - The collection name of the previously installed CEP-78 NFT contract from which we will be minting. - -3. `--session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"` - - The collection name of the NFT to be minted. - -4. `--session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'"` - - Metadata describing the NFT to be minted, passed in as a `string`. - -
-Casper client command without comments - -```bash - -casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ ---payment-amount 5000000000 \ --k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ ---session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \ ---session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'" \ ---session-arg "collection_name:string='cep78_'"` \ ---session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ ---session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'" - -``` - -
- -## Transferring NFTs Between Users - -Below is an example of a `casper-client` command that uses the `transfer` function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with `node-2` to the user associated with `node-3`. - -- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm` - -1. `--session-arg "nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'"` - - The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred. - -2. `--session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"` - - The account hash of the user that currently owns the NFT and wishes to transfer it. - -3. `--session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'"` - - The account hash of the user that will receive the NFT. - -4. `--session-arg "is_hash_identifier_mode:bool='false'"` - - Argument that the hash identifier mode is ordinal, thereby requiring a `token_id` rather than a `token_hash`. - -5. `--session-arg "token_id:u64='0'"` - - The `token_id` of the NFT to be transferred. - -
-Casper client command without comments - -```bash -casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ ---payment-amount 5000000000 \ --k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \ ---session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \ ---session-arg "nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'" \ ---session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \ ---session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \ ---session-arg "is_hash_identifier_mode:bool='false'" \ ---session-arg "token_id:u64='0'" -``` - -
- -## Burning an NFT - -Below is an example of a `casper-client` command that uses the `burn` function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone. - -- `casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem` - -1. `--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5` - - The session hash corresponding to the NFT's contract hash. - -2. `--session-entry-point "burn"` - - The entrypoint corresponding to the `burn` function. - -3. `--session-arg "token_id:u64='1'"` - - The token ID for the NFT to be burned. If the `identifier_mode` is not set to `Ordinal`, you must provide the `token_hash` instead. - -
-Casper client command without comments - -```bash -casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ ---payment-amount 5000000000 \ --k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \ ---session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \ ---session-entry-point "burn" \ ---session-arg "token_id:u64='1'" -``` - -
\ No newline at end of file