Skip to content

Commit

Permalink
Merge branch 'dev' into zh-sre-556
Browse files Browse the repository at this point in the history
  • Loading branch information
TomVasile authored Aug 18, 2022
2 parents c3a6dc4 + f01d13c commit e7d6863
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 182 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ build-contract:
cd client/balance_of_session && cargo build --release --target wasm32-unknown-unknown
cd client/owner_of_session && cargo build --release --target wasm32-unknown-unknown
cd client/get_approved_session && cargo build --release --target wasm32-unknown-unknown
cd client/minting_contract && cargo build --release --target wasm32-unknown-unknown
cd client/transfer_session && cargo build --release --target wasm32-unknown-unknown
cd test-contracts/minting_contract && cargo build --release --target wasm32-unknown-unknown
wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm
wasm-strip client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm
wasm-strip client/balance_of_session/target/wasm32-unknown-unknown/release/balance_of_call.wasm
wasm-strip client/owner_of_session/target/wasm32-unknown-unknown/release/owner_of_call.wasm
wasm-strip client/get_approved_session/target/wasm32-unknown-unknown/release/get_approved_call.wasm
wasm-strip client/minting_contract/target/wasm32-unknown-unknown/release/minting_contract.wasm
wasm-strip client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm
wasm-strip test-contracts/minting_contract/target/wasm32-unknown-unknown/release/minting_contract.wasm

test: build-contract
mkdir -p tests/wasm
Expand All @@ -28,8 +28,8 @@ test: build-contract
cp client/balance_of_session/target/wasm32-unknown-unknown/release/balance_of_call.wasm tests/wasm
cp client/owner_of_session/target/wasm32-unknown-unknown/release/owner_of_call.wasm tests/wasm
cp client/get_approved_session/target/wasm32-unknown-unknown/release/get_approved_call.wasm tests/wasm
cp client/minting_contract/target/wasm32-unknown-unknown/release/minting_contract.wasm tests/wasm
cp client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm tests/wasm
cp test-contracts/minting_contract/target/wasm32-unknown-unknown/release/minting_contract.wasm tests/wasm
cd tests && cargo test

clippy:
Expand Down
196 changes: 191 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CEP-78: Enhanced NFT standard

## Design goals
## Design Goals
- DApp developer attempting to create an NFT contract should be able to install the contract as is,
configured for the specific builtin behavior they want their NFT contract instance to have. Must work out of the box.
- Reference implementation must be straightforward, clear, and obvious.
Expand All @@ -13,9 +13,17 @@
- A NFT contract instance must validate provided metadata against the specified metadata schema for that contract.
- Standardized session code to interact with an NFT contract instance must be usable as is, so that a given DApp developer doesn't have to write any Wasm producing logic for normal usage of NFT contract instances produced by this contract.

## Features and usage
## Table of Contents

### Modalities
1) [Modalities](#modalities)

2) [Usage](#usage)

3) [Installing and Interacting with the Contract using the Rust Casper Client](#installing-and-interacting-with-the-contract-using-the-rust-casper-client)

4) [Test Suite and Specification](#test-suite-and-specification)

## Modalities

The enhanced NFT implementation supports various 'modalities' which dictate the behavior of a specific instance of a
contract. Modalities represent the common expectations around contract usage and behavior.
Expand All @@ -37,7 +45,7 @@ In all the three mentioned modes, the owner entity is currently restricted to `A
This `Ownership` mode is a required installation parameter and cannot be changed once the contract has been installed.
The mode is passed in as `u8` value to the `"ownership_mode"` runtime argument.

| Mode | u8 |
| Ownership | u8 |
|--------------|-----|
| Minter | 0 |
| Assigned | 1 |
Expand Down Expand Up @@ -247,6 +255,9 @@ The `MetadataMutability` option of `Mutable` cannot be used in conjunction with
#### Installing the contract.

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

The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. User's wishing to build the Wasm themselves can pull the code and the `make build-contract` provided in the included Makefile. Please not, however, as part of building the contract, you will need to install `wasm-strip`.

The `call` method will install the contract with the necessary entrypoints and call `init()` entry point to allow the contract to self initialize and setup the necessary state to allow for operation,
The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract.

Expand Down Expand Up @@ -293,7 +304,182 @@ folder within the project folder.
| `"owner_of"` | `client/owner_of_session` |


## Test Suite and specification.
### Installing and Interacting with the Contract using the Rust Casper Client

This contract code installs an instance of the CEP-78 enhanced NFT standard as per session arguments provided at the time of installation.

#### Installing the Contract

Installing the enhanced NFT contract to global state requires the use of a [Deploy](https://docs.casperlabs.io/dapp-dev-guide/building-dapps/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. This value cannot be changed at a later date.
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 the main [README](https://github.com/casper-ecosystem/cep-78-enhanced-nft).

<details>
<summary><b>Casper client command without comments</b></summary>

```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'"

```

</details>

#### Minting an NFT

Below is an example of a `casper-client` command that uses the `mint` function of hte contract to mint an NFT for the user associated with `node-1` in an [NCTL environment](https://docs.casperlabs.io/dapp-dev-guide/building-dapps/nctl-test/).

* `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/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 "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"`

The account hash of the account receiving the minted token.

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`.



<details>
<summary><b>Casper client command without comments</b></summary>

```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/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm
--session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'"
--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\"}'"

```

</details>

#### 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 500000000000 -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.

<details>
<summary><b>Casper client command without comments</b></summary>

```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-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'"

```

</details>

#### 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 accessibly by anyone.

* `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`

1) `--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5`

The session hash corresponding to the NFT's contract hash.

2) `--session-entry-point "burn"`

The entry point 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.

<details>
<summary><b>Casper client command without comments</b></summary>

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-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5
--session-entry-point "burn"
--session-arg "token_id:u64='1'"

</details>

## Test Suite and Specification

The expected behavior of the NFT contract implementation is asserted by its test suite found in the `tests` folder.
The test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors
Expand Down
Loading

0 comments on commit e7d6863

Please sign in to comment.