Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Missing Example/Test-Case: Mint NFTs with Different Sets of Metadata and Retrieve That Metadata #77

Open
johnnyshankman opened this issue Oct 30, 2021 · 5 comments

Comments

@johnnyshankman
Copy link

johnnyshankman commented Oct 30, 2021

It's unclear how you mint two different singular NFTs on the same contract with different metadata, which is usually the case for NFT contracts. The token_metadata endpoint is also a little arcane, as it asks for a lambda as the first parameter and I'm not sure what sort of function it expects.

Everything is catered toward a range of NFT IDs with the same metadata.

(* range of nft tokens *)
type token_def =
[@layout:comb]
{
  from_ : nat;
  to_ : nat;
}

The test cases only show one case where you want to mint two NFTs with the same metadata:
https://github.com/oxheadalpha/smart-contracts/blob/master/nft_assets/tezos_fa2_nft_tests/test_fa2.py#L132-L153

So my question is how do I do two?
Is this how I would do two separate ones?

        self.fa2.mint_tokens(
            {
                "metadata": token_metadata1,
                "token_def": {
                    "from_": 0,
                    "to_": 1,
                },
                "owners": [owner1_address],
            }
        self.fa2.mint_tokens(
            {
                "metadata": token_metadata2,
                "token_def": {
                    "from_": 1,
                    "to_": 2,
                },
                "owners": [owner1_address],
            }

Furthermore, how do I check the metadata for a single token with token_metadata?

(**
Implementation of the FA2 interface for the NFT contract supporting multiple
types of NFTs. Each NFT type is represented by the range of token IDs - `token_def`.
 *)

What does "type" mean? It's unclear. A non-fungible token is 1-1 and therefore it's always a unique type.

@johnnyshankman
Copy link
Author

johnnyshankman commented Oct 30, 2021

Although I can't manage to write a working lambda, I've managed to assert from this:

(** Finds a definition of the token type (token_id range) associated with the provided token id *)
let find_token_def (tid, token_defs : token_id * (token_def set)) : token_def =
  let tdef = Set.fold (fun (res, d : (token_def option) * token_def) ->
    match res with
    | Some r -> res
    | None ->
      if tid >= d.from_ && tid < d.to_
      then  Some d
      else (None : token_def option)
  ) token_defs (None : token_def option)
  in
  match tdef with
  | None -> (failwith fa2_token_undefined : token_def)
  | Some d -> d

That it seems to match on tid being greater than or equal to the from, but less than the to (exclusive).

So if I want data for token 3 and there are four pairs in storage

Pair(1, 2) -> url1
Pair(2, 3) -> url2
Pair(3, 4) -> url3
Pair(4, 5) -> url4

It will always pick Pair(3,4) with url3 as

3 >= 3 is true
3 < 4  is true

And

3 >= 2 is true
3 < 3  is false

And

3 >= 4 is false
3 < 5  is true

And

3 >= 1 is true
3 < 2  is false

@johnnyshankman
Copy link
Author

johnnyshankman commented Oct 30, 2021

I think we should put this more clearly somewhere as an example for future devs as it's a pretty odd pattern for something where each token inherently is supposed to have unique data.

I still have no idea how to pass in the lambda for getting token data.

@johnnyshankman johnnyshankman changed the title Missing Example: How To Mint NFTs with Two Different Sets of Metadata Missing Example/Test-Case: Mint NFTs with Different Sets of Metadata and Retrieve That Metadata Oct 31, 2021
@emishur
Copy link
Collaborator

emishur commented Nov 4, 2021

The token_metadata endpoint is also a little arcane, as it asks for a lambda as the first parameter and I'm not sure what sort of function it expects.

I still have no idea how to pass in the lambda for getting token data.

This is a special way to implement contract view entry points. Tezos will have Solidity-like view entry points with the next protocol update. At the moment, view entry points use continuation passing style pattern when the parameter contains a callback lambda.

If the contract A wants to get some value from the contract B, it should call contract's A view entry point passing parameters (like token_id) and a callback. Contract B then will call a provided callback entry point of the contract A, passing the requested value.

In general, view entry points cannot be called off-chain (only by other contracts). But Taquito library has special API which lets to inspect view entry points off-chain: https://tezostaquito.io/docs/lambda_view/

@emishur
Copy link
Collaborator

emishur commented Nov 4, 2021

It's unclear how you mint two different singular NFTs on the same contract with different metadata ...
Everything is catered toward a range of NFT IDs with the same metadata.

Yes, this is a special NFT contract which represents "semi-fungible" NFTs.
You might want to look at NFT collectibles example: https://github.com/oxheadalpha/smart-contracts/tree/master/collectibles
https://github.com/oxheadalpha/smart-contracts/blob/master/collectibles/ligo/src/fa2_single_asset.mligo contract can be originated with a fixed NFT collection where each NFT has different metadata.

You may also have a look at https://github.com/tqtezos/minter-sdk which has a variety of fungible and non-fungible token contracts implementation or take the NFT contract from https://github.com/oxheadalpha/nft-tutorial

@johnnyshankman
Copy link
Author

@emishur thank you so much for all of this information. really appreciated

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants