0

I am doing a contract to Mint Nfts on Tezos on Legacy SmartPY ide (because Tezos tutorial uses it). I already created Nfts but only in single edition, now i'm trying to do a Multi-edition, but the IDE says this error:

Error: Error in Scenario
File "smartML/core/compiler.ml", line 2520, characters 12-18: Assertion failed

My code is:

import smartpy as sp

FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py")

class Token(FA2.Admin, FA2.MintNft, FA2.Fa2Nft):
    def __init__(self, admin, **kwargs):
        FA2.Fa2Nft.__init__(self, **kwargs)
        FA2.Admin.__init__(self, admin)

class Marketplace(sp.Contract):
    def __init__(self, token, metadata, admin):
        self.init(
            token=token,
            metadata=metadata,
            admin=admin,
            data = sp.big_map(
                tkey=sp.TNat,
                tvalue=sp.TList(
                    sp.TRecord(
                        holder=sp.TAddress,
                        author=sp.TAddress,
                        amount=sp.TMutez,
                        token_id=sp.TNat,
                        editions=sp.TNat,
                        collectable=sp.TBool))),
            token_id=0)

    @sp.entry_point
    def mint(self, params):
        c = sp.contract(
            sp.TList(sp.TRecord(to_=sp.TAddress, metadata=sp.TMap(sp.TString, sp.TBytes)).layout(("to_", "metadata"))),
            self.data.token,
            entry_point="mint").open_some()

        args = [sp.record(to_=params.to_, metadata=params.metadata)]
        sp.transfer(args, sp.mutez(0), c)

        editions_list = sp.list([])

        sp.for i in sp.range(1, params.editions + 1):
            edition_record = sp.record(
                holder=self.data.admin,
                author=params.to_,
                amount=params.amount,
                token_id=self.data.token_id,
                editions=i,
                collectable=True)
            
            editions_list.push(edition_record)

        self.data.data[self.data.token_id] = editions_list

        self.data.token_id += 1

@sp.add_test(name = "Non Fungible Token")
def test():
    scenario = sp.test_scenario()
    
    admin = sp.test_account("admin")
    mark = sp.test_account("user1")
    elon = sp.test_account("user2")

    token_contract = Token(
        admin=admin.address,
        metadata=sp.utils.metadata_of_url(
            "ipfs://QmW8jPMdBmFvsSEoLWPPhaozN6jGQFxxkwuMLtVFqEy6Fb"))
    scenario += token_contract

    scenario.h1("MarketPlace")
    marketplace = Marketplace(
        token_contract.address,
        sp.utils.metadata_of_url(
            "ipfs://QmW8jPMdBmFvsSEoLWPPhaozN6jGQFxxkwuMLtVFqEy6Fb"
        ), admin.address)
    scenario += marketplace

    marketplace.mint(
        to_=admin.address,
        amount=sp.tez(100),
        editions=sp.nat(5),
        metadata={"": sp.pack("ipfs://QmbR82U2yKHbhjve45rqSF9h25s5aFKhMcpZkLRvXRnos6")}
    ).run(sender=admin)
    
    token_contract.set_administrator(marketplace.address).run(sender=admin)
    
    marketplace.mint(
        to_=mark.address,
        amount=sp.tez(100),
        editions=sp.nat(5),
        metadata={"": sp.pack("ipfs://bafyreibwl5hhjgrat5l7cmjlv6ppwghm6ijygpz2xor2r6incfcxnl7y3e/metadata.json")}
    ).run(sender=admin)
    
    marketplace.mint(to_=mark.address, amount=sp.mutez(5_600_000), editions=5, metadata={"": sp.pack("123423")}).run(sender=admin)

My ideia is to do a list of tokens, each one with one ID (token id). In this list will contain all holders (owners) of each token edition.

1 Answer 1

0

There are two things which are raising errors in the contract.

  1. The token_contract.set_administrator() should be called before the first marketplace.mint(), because the marketplace will need to become the admin of the token for minting.
  2. editions_list should be a local variable, instead of a literal. Since you are adding the elements into it one by one, its values are updating every time the elements are pushed. So, it should be editions_list = sp.local('editions_list', []). Also to access its value, do editions_list.value.

So, the whole contract becomes:

import smartpy as sp

FA2 = sp.io.import_script_from_url("https://legacy.smartpy.io/templates/fa2_lib.py")

class Token(FA2.Admin, FA2.MintNft, FA2.Fa2Nft):
    def __init__(self, admin, **kwargs):
        FA2.Fa2Nft.__init__(self, **kwargs)
        FA2.Admin.__init__(self, admin)

class Marketplace(sp.Contract):
    def __init__(self, token, metadata, admin):
        self.init(
            token=token,
            metadata=metadata,
            admin=admin,
            data = sp.big_map(
                tkey=sp.TNat,
                tvalue=sp.TList(
                    sp.TRecord(
                        holder=sp.TAddress,
                        author=sp.TAddress,
                        amount=sp.TMutez,
                        token_id=sp.TNat,
                        editions=sp.TNat,
                        collectable=sp.TBool))),
            token_id=0)

    @sp.entry_point
    def mint(self, params):
        c = sp.contract(
            sp.TList(sp.TRecord(to_=sp.TAddress, metadata=sp.TMap(sp.TString, sp.TBytes)).layout(("to_", "metadata"))),
            self.data.token,
            entry_point="mint").open_some()

        args = [sp.record(to_=params.to_, metadata=params.metadata)]
        sp.transfer(args, sp.mutez(0), c)

        editions_list = sp.local('editions_list', [])

        sp.for i in sp.range(1, params.editions + 1):
            edition_record = sp.record(
                holder=self.data.admin,
                author=params.to_,
                amount=params.amount,
                token_id=self.data.token_id,
                editions=i,
                collectable=True)
            
            editions_list.value.push(edition_record)

        self.data.data[self.data.token_id] = editions_list.value

        self.data.token_id += 1

@sp.add_test(name = "Non Fungible Token")
def test():
    scenario = sp.test_scenario()
    
    admin = sp.test_account("admin")
    mark = sp.test_account("user1")
    elon = sp.test_account("user2")

    token_contract = Token(
        admin=admin.address,
        metadata=sp.utils.metadata_of_url(
            "ipfs://QmW8jPMdBmFvsSEoLWPPhaozN6jGQFxxkwuMLtVFqEy6Fb"))
    scenario += token_contract

    scenario.h1("MarketPlace")
    marketplace = Marketplace(
        token_contract.address,
        sp.utils.metadata_of_url(
            "ipfs://QmW8jPMdBmFvsSEoLWPPhaozN6jGQFxxkwuMLtVFqEy6Fb"
        ), admin.address)
    scenario += marketplace

    token_contract.set_administrator(marketplace.address).run(sender=admin)

    marketplace.mint(
        to_=admin.address,
        amount=sp.tez(100),
        editions=sp.nat(5),
        metadata={"": sp.pack("ipfs://QmbR82U2yKHbhjve45rqSF9h25s5aFKhMcpZkLRvXRnos6")}
    ).run(sender=admin)

    marketplace.mint(
        to_=mark.address,
        amount=sp.tez(100),
        editions=sp.nat(5),
        metadata={"": sp.pack("ipfs://bafyreibwl5hhjgrat5l7cmjlv6ppwghm6ijygpz2xor2r6incfcxnl7y3e/metadata.json")}
    ).run(sender=admin)
    
    marketplace.mint(to_=mark.address, amount=sp.mutez(5_600_000), editions=5, metadata={"": sp.pack("123423")}).run(sender=admin)

Here's the diff

1
  • Thank you, it worked very well! Commented Sep 21, 2023 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.