ERC 1155 marketplace

Its a ticket nft minter
Whats wrong with this code I cant figure out how to execute it

pragma solidity >=0.7.0 <0.9.0;

import “@openzeppelin/contracts/utils/Context.sol”;

import “@openzeppelin/contracts/access/AccessControl.sol”;

import “@openzeppelin/contracts/token/ERC1155/ERC1155.sol”;

import “@openzeppelin/contracts/utils/Counters.sol”;

contract FestivalNFT is Context, AccessControl, ERC1155 {

using Counters for Counters.Counter;

Counters.Counter private _ticketIds;

Counters.Counter private _saleTicketId;

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

struct TicketDetails {

    uint256 purchasePrice;

    uint256 sellingPrice;

    bool forSale;

}

address private _organiser;

address[] private customers;

uint256[] private ticketsForSale;

uint256 private _ticketPrice;

uint256 private _totalSupply;

mapping(uint256 => TicketDetails) private _ticketDetails;

mapping(address => uint256[]) private purchasedTickets;

constructor(

    string memory EventName,

    string memory EventSymbol,

    uint256 ticketPrice,

    uint256 totalSupply,

    address organiser

) public ERC1155(EventName, EventSymbol) {

    _setupRole(MINTER_ROLE, organiser);

    _ticketPrice = ticketPrice;

    _totalSupply = totalSupply;

    _organiser = organiser;

}

modifier isValidTicketCount {

    require(

        _ticketIds.current() < _totalSupply,

        "Maximum ticket limit exceeded!"

    );

    _;

}

modifier isMinterRole {

    require(

        hasRole(MINTER_ROLE, _msgSender()),

        "User must have minter role to mint"

    );

    _;

}

modifier isValidSellAmount(uint256 ticketId) {

    uint256 purchasePrice = _ticketDetails[ticketId].purchasePrice;

    uint256 sellingPrice = _ticketDetails[ticketId].sellingPrice;

    require(

        purchasePrice + ((purchasePrice * 110) / 100) > sellingPrice,

        "Re-selling price is more than 110%"

    );

    _;

}

/*

 * Mint new tickets and assign it to operator

 * Access controlled by minter only

 * Returns new ticketId

 */

function mint(address operator)

    internal

    virtual

    isMinterRole

    returns (uint256)

{

    _ticketIds.increment();

    uint256 newTicketId = _ticketIds.current();

    _mint(operator, newTicketId);

    _ticketDetails[newTicketId] = TicketDetails({

        purchasePrice: _ticketPrice,

        sellingPrice: 0,

        forSale: false

    });

    return newTicketId;

}

/*

 * Bulk mint specified number of tickets to assign it to a operator

 * Modifier to check the ticket count is less than total supply

 */

function bulkMintTickets(uint256 numOfTickets, address operator)

    public

    virtual

    isValidTicketCount

{

    require(

        (ticketCounts() + numOfTickets) <= 1000,

        "Number of tickets exceeds maximum ticket count"

    );

    for (uint256 i = 0; i < numOfTickets; i++) {

        mint(operator);

    }

}

/*

 * Primary purchase for the tickets

 * Adds new customer if not exists

 * Adds buyer to tickets mapping

 * Update ticket details

 */

function transferTicket(address buyer) public {

    _saleTicketId.increment();

    uint256 saleTicketId = _saleTicketId.current();

    require(

        msg.sender == ownerOf(saleTicketId),

        "Only initial purchase allowed"

    );

    transferFrom(ownerOf(saleTicketId), buyer, saleTicketId);

    if (!isCustomerExist(buyer)) {

        customers.push(buyer);

    }

    purchasedTickets[buyer].push(saleTicketId);

}

/*

 * Secondary purchase for the tickets

 * Modifier to validate that the selling price shouldn't exceed 110% of purchase price for peer to peer transfers

 * Adds new customer if not exists

 * Adds buyer to tickets mapping

 * Remove ticket from the seller and from sale

 * Update ticket details

 */

function secondaryTransferTicket(address buyer, uint256 saleTicketId)

    public

    isValidSellAmount(saleTicketId)

{

    address seller = ownerOf(saleTicketId);

    uint256 sellingPrice = _ticketDetails[saleTicketId].sellingPrice;

    transferFrom(seller, buyer, saleTicketId);

    if (!isCustomerExist(buyer)) {

        customers.push(buyer);

    }

    purchasedTickets[buyer].push(saleTicketId);

    removeTicketFromCustomer(seller, saleTicketId);

    removeTicketFromSale(saleTicketId);

    _ticketDetails[saleTicketId] = TicketDetails({

        purchasePrice: sellingPrice,

        sellingPrice: 0,

        forSale: false

    });

}

/*

 * Add ticket for sale with its details

 * Validate that the selling price shouldn't exceed 110% of purchase price

 * Organiser can not use secondary market sale

 */

function setSaleDetails(

    uint256 ticketId,

    uint256 sellingPrice,

    address operator

) public {

    uint256 purchasePrice = _ticketDetails[ticketId].purchasePrice;

    require(

        purchasePrice + ((purchasePrice * 110) / 100) > sellingPrice,

        "Re-selling price is more than 110%"

    );

    // Should not be an organiser

    require(

        !hasRole(MINTER_ROLE, _msgSender()),

        "Functionality only allowed for secondary market"

    );

    _ticketDetails[ticketId].sellingPrice = sellingPrice;

    _ticketDetails[ticketId].forSale = true;

    if (!isSaleTicketAvailable(ticketId)) {

        ticketsForSale.push(ticketId);

    }

    approve(operator, ticketId);

}

// Get ticket actual price

function getTicketPrice() public view returns (uint256) {

    return _ticketPrice;

}

// Get organiser's address

function getOrganiser() public view returns (address) {

    return _organiser;

}

// Get current ticketId

function ticketCounts() public view returns (uint256) {

    return _ticketIds.current();

}

// Get next sale ticketId

function getNextSaleTicketId() public view returns (uint256) {

    return _saleTicketId.current();

}

// Get selling price for the ticket

function getSellingPrice(uint256 ticketId) public view returns (uint256) {

    return _ticketDetails[ticketId].sellingPrice;

}

// Get all tickets available for sale

function getTicketsForSale() public view returns (uint256[] memory) {

    return ticketsForSale;

}

// Get ticket details

function getTicketDetails(uint256 ticketId)

    public

    view

    returns (

        uint256 purchasePrice,

        uint256 sellingPrice,

        bool forSale

    )

{

    return (

        _ticketDetails[ticketId].purchasePrice,

        _ticketDetails[ticketId].sellingPrice,

        _ticketDetails[ticketId].forSale

    );

}

// Get all tickets owned by a customer

function getTicketsOfCustomer(address customer)

    public

    view

    returns (uint256[] memory)

{

    return purchasedTickets[customer];

}

// Utility function to check if customer exists to avoid redundancy

function isCustomerExist(address buyer) internal view returns (bool) {

    for (uint256 i = 0; i < customers.length; i++) {

        if (customers[i] == buyer) {

            return true;

        }

    }

    return false;

}

// Utility function used to check if ticket is already for sale

function isSaleTicketAvailable(uint256 ticketId)

    internal

    view

    returns (bool)

{

    for (uint256 i = 0; i < ticketsForSale.length; i++) {

        if (ticketsForSale[i] == ticketId) {

            return true;

        }

    }

    return false;

}

// Utility function to remove ticket owned by customer from customer to ticket mapping

function removeTicketFromCustomer(address customer, uint256 ticketId)

    internal

{

    uint256 numOfTickets = purchasedTickets[customer].length;

    for (uint256 i = 0; i < numOfTickets; i++) {

        if (purchasedTickets[customer][i] == ticketId) {

            for (uint256 j = i + 1; j < numOfTickets; j++) {

                purchasedTickets[customer][j - 1] = purchasedTickets[

                    customer

                ][j];

            }

            purchasedTickets[customer].pop();

        }

    }

}

// Utility function to remove ticket from sale list

function removeTicketFromSale(uint256 ticketId) internal {

    uint256 numOfTickets = ticketsForSale.length;

    for (uint256 i = 0; i < numOfTickets; i++) {

        if (ticketsForSale[i] == ticketId) {

            for (uint256 j = i + 1; j < numOfTickets; j++) {

                ticketsForSale[j - 1] = ticketsForSale[j];

            }

            ticketsForSale.pop();

        }

    }

}

}

What part doesn’t work?

I have edit and write it on vscode
but when I put it in remix everything crashed with many error

Maybe is because of quotes, what is the first error that you get?

This is the first one
could you deploy it your self, please

Remix does not work directly with the openzeppelin contract module, you have to specify the URL for each of the importing contracts.

I advice you to take a look into our amazing course Ethereum Smart Contract Programming 101 to understand the basics on how remix works. :nerd_face:

Carlos Z

1 Like

I do really want to use the course but I don’t have a credit card(there is no support in my country) either the money

instead of these lines you should have something like

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";

with direct paths to GitHub where those sources can be found.
This is only an example of how you should use imports from GitHub.