contract Oshen is ERC1155 {

    event minterRemoved(address minter);
    event minterAdded(address minter);

    uint256 newItemId = 1;
    address public owner;
    mapping(address => bool) private minters;
    uint256 public mintersCount;
    address[] private _minters;

    constructor (string memory name, string memory symbol, string memory tokenURIPrefix) ERC1155 (name, symbol) {
        owner = msg.sender;
        minters[msg.sender] = true;
        _minters.push(msg.sender);
        mintersCount = 1;
        _setTokenURIPrefix(tokenURIPrefix);

    }

    modifier onlyOwner() {
        require(owner == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    /** @dev change the Ownership from current owner to newOwner address
        @param newOwner : newOwner address */    

    function ownerTransfership(address newOwner) public onlyOwner returns(bool) {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        owner = newOwner;
        return true;
    }

    function setBaseURI(string memory _baseURI) public onlyOwner {
        _setTokenURIPrefix(_baseURI);
    }

    function addMinter(address _minter) public onlyOwner {
        require(_minter != address(0),"Minter: minter is the zero address");
        require(!minters[_minter],"Minter: minter already exists");
        _minters.push(_minter);
        mintersCount += 1;
        minters[_minter] = true;
        emit minterAdded(_minter);
    } 

    function removeMinter(address _minter) public onlyOwner {
        require(_minter != address(0),"Minter: minter is the zero address");
        require(minters[_minter],"Minter: minter not exists");   
        minters[_minter] = false;
        mintersCount -= 1; 
        emit minterRemoved(_minter);        
    }

    function getMinters() public view returns(address[] memory) {
        address[] memory listOfMinters = new address[] (mintersCount);
        for(uint256 i = 0; i < _minters.length ; i++) {
            if(minters[_minters[i]]) {
                listOfMinters[i] = _minters[i];
            }
        }
        return ( listOfMinters);
    } 

    function mint(string memory uri, uint256 supply, uint256 fee)  public {
        require(minters[msg.sender],"ERC1155: caller is not minter");        
        _mint(newItemId, supply, uri, fee);
        newItemId = newItemId + 1;
    }

    function burn(uint256 tokenId, uint256 supply) public {
        _burn(msg.sender, tokenId, supply);
    }

    function burnBatch(address account, uint256[] memory tokenIds, uint256[] memory amounts) public {
        _burnBatch(account, tokenIds, amounts);
    }
}
function ownerTransfership(address newOwner) public onlyOwner returns(bool) {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    owner = newOwner;
    return true;
}

/** @dev change the Ownership from current owner to newOwner address
 @param newOwner : newOwner address */