/**
* Copyright 2018 ZeroEx Intl.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/pragmasolidity ^0.5.12;/**
* Utility library of inline functions on addresses
*/libraryAddress{
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param account address of the account to check
* @return whether the target address is a contract
*/functionisContract(address account) internalviewreturns (bool) {
bytes32 codehash;
bytes32 accountHash =0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// XXX Currently there is no better way to check if there is a contract in an address// than to check the size of the code at that address.// See https://ethereum.stackexchange.com/a/14016/36603// for more details about how this works.// TODO Check this again before the Serenity release, because all addresses will be// contracts then.assembly { codehash :=extcodehash(account) }
return (codehash !=0x0&& codehash != accountHash);
}
}
Contract Source Code
File 2 of 12: ERC1155.sol
pragmasolidity ^0.5.12;import"../../interfaces/IERC165.sol";
import"../../utils/SafeMath.sol";
import"../../interfaces/IERC1155TokenReceiver.sol";
import"../../interfaces/IERC1155.sol";
import"../../utils/Address.sol";
/**
* @dev Implementation of Multi-Token Standard contract
*/contractERC1155isIERC165{
usingSafeMathforuint256;
usingAddressforaddress;
/***********************************|
| Variables and Events |
|__________________________________*/// onReceive function signaturesbytes4constantinternal ERC1155_RECEIVED_VALUE =0xf23a6e61;
bytes4constantinternal ERC1155_BATCH_RECEIVED_VALUE =0xbc197c81;
// Objects balancesmapping (address=>mapping(uint256=>uint256)) internal balances;
// Operator Functionsmapping (address=>mapping(address=>bool)) internal operators;
// EventseventTransferSingle(addressindexed _operator, addressindexed _from, addressindexed _to, uint256 _id, uint256 _amount);
eventTransferBatch(addressindexed _operator, addressindexed _from, addressindexed _to, uint256[] _ids, uint256[] _amounts);
eventApprovalForAll(addressindexed _owner, addressindexed _operator, bool _approved);
eventURI(string _uri, uint256indexed _id);
/***********************************|
| Public Transfer Functions |
|__________________________________*//**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/functionsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytesmemory _data)
public{
require((msg.sender== _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR");
require(_to !=address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT");
// require(_amount >= balances[_from][_id]) is not necessary since checked with safemath operations
_safeTransferFrom(_from, _to, _id, _amount);
_callonERC1155Received(_from, _to, _id, _amount, _data);
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/functionsafeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytesmemory _data)
public{
// Requirementsrequire((msg.sender== _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR");
require(_to !=address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT");
_safeBatchTransferFrom(_from, _to, _ids, _amounts);
_callonERC1155BatchReceived(_from, _to, _ids, _amounts, _data);
}
/***********************************|
| Internal Transfer Functions |
|__________________________________*//**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
*/function_safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
internal{
// Update balances
balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount
balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount// Emit eventemit TransferSingle(msg.sender, _from, _to, _id, _amount);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
*/function_callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, bytesmemory _data)
internal{
// Check if recipient is contractif (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received(msg.sender, _from, _id, _amount, _data);
require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
}
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
*/function_safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
internal{
require(_ids.length== _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");
// Number of transfer to executeuint256 nTransfer = _ids.length;
// Executing all transfersfor (uint256 i =0; i < nTransfer; i++) {
// Update storage balance of previous bin
balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
}
// Emit eventemit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
*/function_callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytesmemory _data)
internal{
// Pass data if recipient is contractif (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived(msg.sender, _from, _ids, _amounts, _data);
require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
}
}
/***********************************|
| Operator Functions |
|__________________________________*//**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/functionsetApprovalForAll(address _operator, bool _approved)
external{
// Update operator status
operators[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return True if the operator is approved, false if not
*/functionisApprovedForAll(address _owner, address _operator)
publicviewreturns (bool isOperator)
{
return operators[_owner][_operator];
}
/***********************************|
| Balance Functions |
|__________________________________*//**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/functionbalanceOf(address _owner, uint256 _id)
publicviewreturns (uint256)
{
return balances[_owner][_id];
}
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/functionbalanceOfBatch(address[] memory _owners, uint256[] memory _ids)
publicviewreturns (uint256[] memory)
{
require(_owners.length== _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH");
// Variablesuint256[] memory batchBalances =newuint256[](_owners.length);
// Iterate over each owner and token IDfor (uint256 i =0; i < _owners.length; i++) {
batchBalances[i] = balances[_owners[i]][_ids[i]];
}
return batchBalances;
}
/***********************************|
| ERC165 Functions |
|__________________________________*//**
* INTERFACE_SIGNATURE_ERC165 = bytes4(keccak256("supportsInterface(bytes4)"));
*/bytes4constantprivate INTERFACE_SIGNATURE_ERC165 =0x01ffc9a7;
/**
* INTERFACE_SIGNATURE_ERC1155 =
* bytes4(keccak256("safeTransferFrom(address,address,uint256,uint256,bytes)")) ^
* bytes4(keccak256("safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)")) ^
* bytes4(keccak256("balanceOf(address,uint256)")) ^
* bytes4(keccak256("balanceOfBatch(address[],uint256[])")) ^
* bytes4(keccak256("setApprovalForAll(address,bool)")) ^
* bytes4(keccak256("isApprovedForAll(address,address)"));
*/bytes4constantprivate INTERFACE_SIGNATURE_ERC1155 =0xd9b67a26;
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/functionsupportsInterface(bytes4 _interfaceID) externalviewreturns (bool) {
if (_interfaceID == INTERFACE_SIGNATURE_ERC165 ||
_interfaceID == INTERFACE_SIGNATURE_ERC1155) {
returntrue;
}
returnfalse;
}
}
Contract Source Code
File 3 of 12: ERC1155Metadata.sol
pragmasolidity ^0.5.11;import"../../interfaces/IERC1155.sol";
/**
* @notice Contract that handles metadata related methods.
* @dev Methods assume a deterministic generation of URI based on token IDs.
* Methods also assume that URI uses hex representation of token IDs.
*/contractERC1155Metadata{
// URI's default URI prefixstringinternal baseMetadataURI;
eventURI(string _uri, uint256indexed _id);
/***********************************|
| Metadata Public Function s |
|__________________________________*//**
* @notice A distinct Uniform Resource Identifier (URI) for a given token.
* @dev URIs are defined in RFC 3986.
* URIs are assumed to be deterministically generated based on token ID
* Token IDs are assumed to be represented in their hex format in URIs
* @return URI string
*/functionuri(uint256 _id) publicviewreturns (stringmemory) {
returnstring(abi.encodePacked(baseMetadataURI, _uint2str(_id), ".json"));
}
/***********************************|
| Metadata Internal Functions |
|__________________________________*//**
* @notice Will emit default URI log event for corresponding token _id
* @param _tokenIDs Array of IDs of tokens to log default URI
*/function_logURIs(uint256[] memory _tokenIDs) internal{
stringmemory baseURL = baseMetadataURI;
stringmemory tokenURI;
for (uint256 i =0; i < _tokenIDs.length; i++) {
tokenURI =string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json"));
emit URI(tokenURI, _tokenIDs[i]);
}
}
/**
* @notice Will emit a specific URI log event for corresponding token
* @param _tokenIDs IDs of the token corresponding to the _uris logged
* @param _URIs The URIs of the specified _tokenIDs
*/function_logURIs(uint256[] memory _tokenIDs, string[] memory _URIs) internal{
require(_tokenIDs.length== _URIs.length, "ERC1155Metadata#_logURIs: INVALID_ARRAYS_LENGTH");
for (uint256 i =0; i < _tokenIDs.length; i++) {
emit URI(_URIs[i], _tokenIDs[i]);
}
}
/**
* @notice Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/function_setBaseMetadataURI(stringmemory _newBaseMetadataURI) internal{
baseMetadataURI = _newBaseMetadataURI;
}
/***********************************|
| Utility Internal Functions |
|__________________________________*//**
* @notice Convert uint256 to string
* @param _i Unsigned integer to convert to string
*/function_uint2str(uint256 _i) internalpurereturns (stringmemory _uintAsString) {
if (_i ==0) {
return"0";
}
uint256 j = _i;
uint256 ii = _i;
uint256 len;
// Get number of byteswhile (j !=0) {
len++;
j /=10;
}
bytesmemory bstr =newbytes(len);
uint256 k = len -1;
// Get each individual ASCIIwhile (ii !=0) {
bstr[k--] =byte(uint8(48+ ii %10));
ii /=10;
}
// Convert to stringreturnstring(bstr);
}
}
Contract Source Code
File 4 of 12: ERC1155MintBurn.sol
pragmasolidity ^0.5.12;import"./ERC1155.sol";
/**
* @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
* a parent contract to be executed as they are `internal` functions
*/contractERC1155MintBurnisERC1155{
/****************************************|
| Minting Functions |
|_______________________________________*//**
* @notice Mint _amount of tokens of a given id
* @param _to The address to mint tokens to
* @param _id Token id to mint
* @param _amount The amount to be minted
* @param _data Data to pass if receiver is contract
*/function_mint(address _to, uint256 _id, uint256 _amount, bytesmemory _data)
internal{
// Add _amount
balances[_to][_id] = balances[_to][_id].add(_amount);
// Emit eventemit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);
// Calling onReceive method if recipient is contract
_callonERC1155Received(address(0x0), _to, _id, _amount, _data);
}
/**
* @notice Mint tokens for each ids in _ids
* @param _to The address to mint tokens to
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
* @param _data Data to pass if receiver is contract
*/function_batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytesmemory _data)
internal{
require(_ids.length== _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH");
// Number of mints to executeuint256 nMint = _ids.length;
// Executing all mintingfor (uint256 i =0; i < nMint; i++) {
// Update storage balance
balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
}
// Emit batch mint eventemit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);
// Calling onReceive method if recipient is contract
_callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, _data);
}
/****************************************|
| Burning Functions |
|_______________________________________*//**
* @notice Burn _amount of tokens of a given token id
* @param _from The address to burn tokens from
* @param _id Token id to burn
* @param _amount The amount to be burned
*/function_burn(address _from, uint256 _id, uint256 _amount)
internal{
//Substract _amount
balances[_from][_id] = balances[_from][_id].sub(_amount);
// Emit eventemit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
}
/**
* @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
* @param _from The address to burn tokens from
* @param _ids Array of token ids to burn
* @param _amounts Array of the amount to be burned
*/function_batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
internal{
require(_ids.length== _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH");
// Number of mints to executeuint256 nBurn = _ids.length;
// Executing all mintingfor (uint256 i =0; i < nBurn; i++) {
// Update storage balance
balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
}
// Emit batch mint eventemit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
}
}
Contract Source Code
File 5 of 12: ERC1155Opensea.sol
pragmasolidity ^0.5.11;import"./ERC1155Tradable.sol";
/**
* @title MyCollectible
* MyCollectible - a contract for my semi-fungible tokens.
*/contractERC1155OpenseaisERC1155Tradable{
stringinternal openseaContractUri;
constructor(address _proxyRegistryAddress, stringmemory _contractUri, stringmemory _metadataUri, stringmemory _name, stringmemory _symbol)
ERC1155Tradable(
_name,
_symbol,
_proxyRegistryAddress
) public{
_setBaseMetadataURI(_metadataUri);
_setContractURI(_contractUri);
}
/**
* @notice Will update the base URL of token's URI
* @param _newContractiURI New base URL of token's URI
*/function_setContractURI(stringmemory _newContractiURI) internal{
openseaContractUri = _newContractiURI;
}
functioncontractURI() publicviewreturns (stringmemory) {
return openseaContractUri;
}
}
Contract Source Code
File 6 of 12: ERC1155Tradable.sol
pragmasolidity ^0.5.12;import"openzeppelin-solidity/contracts/ownership/Ownable.sol";
import'multi-token-standard/contracts/tokens/ERC1155/ERC1155.sol';
import'multi-token-standard/contracts/tokens/ERC1155/ERC1155Metadata.sol';
import'multi-token-standard/contracts/tokens/ERC1155/ERC1155MintBurn.sol';
import"./Strings.sol";
contractOwnableDelegateProxy{ }
contractProxyRegistry{
mapping(address=> OwnableDelegateProxy) public proxies;
}
/**
* @title ERC1155Tradable
* ERC1155Tradable - ERC1155 contract that whitelists an operator address, has create and mint functionality, and supports useful standards from OpenZeppelin,
like _exists(), name(), symbol(), and totalSupply()
*/contractERC1155TradableisERC1155, ERC1155MintBurn, ERC1155Metadata, Ownable{
usingStringsforstring;
address proxyRegistryAddress;
uint256private _currentTokenID =0;
mapping (uint256=>address) public creators;
mapping (uint256=>uint256) public tokenSupply;
// Contract namestringpublic name;
// Contract symbolstringpublic symbol;
/**
* @dev Require msg.sender to be the creator of the token id
*/modifiercreatorOnly(uint256 _id) {
require(creators[_id] ==msg.sender, "ERC1155Tradable#creatorOnly: ONLY_CREATOR_ALLOWED");
_;
}
/**
* @dev Require msg.sender to own more than 0 of the token id
*/modifierownersOnly(uint256 _id) {
require(balances[msg.sender][_id] >0, "ERC1155Tradable#ownersOnly: ONLY_OWNERS_ALLOWED");
_;
}
constructor(stringmemory _name,
stringmemory _symbol,
address _proxyRegistryAddress
) public{
name = _name;
symbol = _symbol;
proxyRegistryAddress = _proxyRegistryAddress;
}
functionuri(uint256 _id
) publicviewreturns (stringmemory) {
require(_exists(_id), "ERC721Tradable#uri: NONEXISTENT_TOKEN");
return Strings.strConcat(
baseMetadataURI,
Strings.uint2str(_id)
);
}
/**
* @dev Returns the total quantity for a token ID
* @param _id uint256 ID of the token to query
* @return amount of token in existence
*/functiontotalSupply(uint256 _id
) publicviewreturns (uint256) {
return tokenSupply[_id];
}
/**
* @dev Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/functionsetBaseMetadataURI(stringmemory _newBaseMetadataURI
) publiconlyOwner{
_setBaseMetadataURI(_newBaseMetadataURI);
}
/**
* @dev Creates a new token type and assigns _initialSupply to an address
* NOTE: remove onlyOwner if you want third parties to create new tokens on your contract (which may change your IDs)
* @param _initialOwner address of the first owner of the token
* @param _initialSupply amount to supply the first owner
* @param _uri Optional URI for this token type
* @param _data Data to pass if receiver is contract
* @return The newly created token ID
*/functioncreate(address _initialOwner,
uint256 _initialSupply,
stringcalldata _uri,
bytescalldata _data
) externalonlyOwnerreturns (uint256) {
uint256 _id = _currentTokenID;
creators[_id] =msg.sender;
if (bytes(_uri).length>0) {
emit URI(_uri, _id);
}
_mint(_initialOwner, _id, _initialSupply, _data);
tokenSupply[_id] = _initialSupply;
_incrementTokenTypeId();
return _id;
}
/**
* @dev Mints some amount of tokens to an address
* @param _to Address of the future owner of the token
* @param _id Token ID to mint
* @param _quantity Amount of tokens to mint
* @param _data Data to pass if receiver is contract
*/functionmint(address _to,
uint256 _id,
uint256 _quantity,
bytesmemory _data
) publiccreatorOnly(_id) {
_mint(_to, _id, _quantity, _data);
tokenSupply[_id] = tokenSupply[_id].add(_quantity);
}
/**
* @dev Mint tokens for each id in _ids
* @param _to The address to mint tokens to
* @param _ids Array of ids to mint
* @param _quantities Array of amounts of tokens to mint per id
* @param _data Data to pass if receiver is contract
*/functionbatchMint(address _to,
uint256[] memory _ids,
uint256[] memory _quantities,
bytesmemory _data
) public{
for (uint256 i =0; i < _ids.length; i++) {
uint256 _id = _ids[i];
require(creators[_id] ==msg.sender, "ERC1155Tradable#batchMint: ONLY_CREATOR_ALLOWED");
uint256 quantity = _quantities[i];
tokenSupply[_id] = tokenSupply[_id].add(quantity);
}
_batchMint(_to, _ids, _quantities, _data);
}
/**
* @dev Change the creator address for given tokens
* @param _to Address of the new creator
* @param _ids Array of Token IDs to change creator
*/functionsetCreator(address _to,
uint256[] memory _ids
) public{
require(_to !=address(0), "ERC1155Tradable#setCreator: INVALID_ADDRESS.");
for (uint256 i =0; i < _ids.length; i++) {
uint256 id = _ids[i];
_setCreator(_to, id);
}
}
/**
* Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-free listings.
*/functionisApprovedForAll(address _owner,
address _operator
) publicviewreturns (bool isOperator) {
// Whitelist OpenSea proxy contract for easy trading.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (address(proxyRegistry.proxies(_owner)) == _operator) {
returntrue;
}
return ERC1155.isApprovedForAll(_owner, _operator);
}
/**
* @dev Change the creator address for given token
* @param _to Address of the new creator
* @param _id Token IDs to change creator of
*/function_setCreator(address _to, uint256 _id) internalcreatorOnly(_id)
{
creators[_id] = _to;
}
/**
* @dev Returns whether the specified token exists by checking to see if it has a creator
* @param _id uint256 ID of the token to query the existence of
* @return bool whether the token exists
*/function_exists(uint256 _id
) internalviewreturns (bool) {
return creators[_id] !=address(0);
}
/**
* @dev increments the value of _currentTokenID
*/function_incrementTokenTypeId() private{
_currentTokenID++;
}
}
Contract Source Code
File 7 of 12: IERC1155.sol
pragmasolidity ^0.5.12;interfaceIERC1155{
// Events/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/eventTransferSingle(addressindexed _operator, addressindexed _from, addressindexed _to, uint256 _id, uint256 _amount);
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/eventTransferBatch(addressindexed _operator, addressindexed _from, addressindexed _to, uint256[] _ids, uint256[] _amounts);
/**
* @dev MUST emit when an approval is updated
*/eventApprovalForAll(addressindexed _owner, addressindexed _operator, bool _approved);
/**
* @dev MUST emit when the URI is updated for a token ID
* URIs are defined in RFC 3986
* The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema"
*/eventURI(string _amount, uint256indexed _id);
/**
* @notice Transfers amount of an _id from the _from address to the _to address specified
* @dev MUST emit TransferSingle event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/functionsafeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytescalldata _data) external;
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev MUST emit TransferBatch event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if length of `_ids` is not the same as length of `_amounts`
* MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/functionsafeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytescalldata _data) external;
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/functionbalanceOf(address _owner, uint256 _id) externalviewreturns (uint256);
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/functionbalanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) externalviewreturns (uint256[] memory);
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @dev MUST emit the ApprovalForAll event on success
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/functionsetApprovalForAll(address _operator, bool _approved) external;
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return True if the operator is approved, false if not
*/functionisApprovedForAll(address _owner, address _operator) externalviewreturns (bool isOperator);
}
Contract Source Code
File 8 of 12: IERC1155TokenReceiver.sol
pragmasolidity ^0.5.12;/**
* @dev ERC-1155 interface for accepting safe transfers.
*/interfaceIERC1155TokenReceiver{
/**
* @notice Handle the receipt of a single ERC1155 token type
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value MUST result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeTransferFrom` function
* @param _from The address which previously owned the token
* @param _id The id of the token being transferred
* @param _amount The amount of tokens being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
*/functiononERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytescalldata _data) externalreturns(bytes4);
/**
* @notice Handle the receipt of multiple ERC1155 token types
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value WILL result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeBatchTransferFrom` function
* @param _from The address which previously owned the token
* @param _ids An array containing ids of each token being transferred
* @param _amounts An array containing amounts of each token being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
*/functiononERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytescalldata _data) externalreturns(bytes4);
/**
* @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
* @param interfaceID The ERC-165 interface ID that is queried for support.s
* @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
* This function MUST NOT consume more than 5,000 gas.
* @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
*/functionsupportsInterface(bytes4 interfaceID) externalviewreturns (bool);
}
Contract Source Code
File 9 of 12: IERC165.sol
pragmasolidity ^0.5.12;/**
* @title ERC165
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
*/interfaceIERC165{
/**
* @notice Query if a contract implements an interface
* @dev Interface identification is specified in ERC-165. This function
* uses less than 30,000 gas
* @param _interfaceId The interface identifier, as specified in ERC-165
*/functionsupportsInterface(bytes4 _interfaceId)
externalviewreturns (bool);
}
Contract Source Code
File 10 of 12: Ownable.sol
pragmasolidity ^0.5.0;/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/contractOwnable{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/constructor () internal{
_owner =msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/functionowner() publicviewreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
require(isOwner());
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/functionisOwner() publicviewreturns (bool) {
returnmsg.sender== _owner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* @notice Renouncing to ownership will leave the contract without an owner.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
*/functionrenounceOwnership() publiconlyOwner{
emit OwnershipTransferred(_owner, address(0));
_owner =address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/functiontransferOwnership(address newOwner) publiconlyOwner{
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/function_transferOwnership(address newOwner) internal{
require(newOwner !=address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
Contract Source Code
File 11 of 12: SafeMath.sol
pragmasolidity ^0.5.12;/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/librarySafeMath{
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522if (a ==0) {
return0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath#mul: OVERFLOW");
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
// Solidity only automatically asserts when dividing by 0require(b >0, "SafeMath#div: DIVISION_BY_ZERO");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b <= a, "SafeMath#sub: UNDERFLOW");
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath#add: OVERFLOW");
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b !=0, "SafeMath#mod: DIVISION_BY_ZERO");
return a % b;
}
}
Contract Source Code
File 12 of 12: Strings.sol
pragmasolidity ^0.5.11;libraryStrings{
// via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.solfunctionstrConcat(stringmemory _a, stringmemory _b, stringmemory _c, stringmemory _d, stringmemory _e) internalpurereturns (stringmemory) {
bytesmemory _ba =bytes(_a);
bytesmemory _bb =bytes(_b);
bytesmemory _bc =bytes(_c);
bytesmemory _bd =bytes(_d);
bytesmemory _be =bytes(_e);
stringmemory abcde =newstring(_ba.length+ _bb.length+ _bc.length+ _bd.length+ _be.length);
bytesmemory babcde =bytes(abcde);
uint k =0;
for (uint i =0; i < _ba.length; i++) babcde[k++] = _ba[i];
for (uint i =0; i < _bb.length; i++) babcde[k++] = _bb[i];
for (uint i =0; i < _bc.length; i++) babcde[k++] = _bc[i];
for (uint i =0; i < _bd.length; i++) babcde[k++] = _bd[i];
for (uint i =0; i < _be.length; i++) babcde[k++] = _be[i];
returnstring(babcde);
}
functionstrConcat(stringmemory _a, stringmemory _b, stringmemory _c, stringmemory _d) internalpurereturns (stringmemory) {
return strConcat(_a, _b, _c, _d, "");
}
functionstrConcat(stringmemory _a, stringmemory _b, stringmemory _c) internalpurereturns (stringmemory) {
return strConcat(_a, _b, _c, "", "");
}
functionstrConcat(stringmemory _a, stringmemory _b) internalpurereturns (stringmemory) {
return strConcat(_a, _b, "", "", "");
}
functionuint2str(uint _i) internalpurereturns (stringmemory _uintAsString) {
if (_i ==0) {
return"0";
}
uint j = _i;
uint len;
while (j !=0) {
len++;
j /=10;
}
bytesmemory bstr =newbytes(len);
uint k = len -1;
while (_i !=0) {
bstr[k--] =byte(uint8(48+ _i %10));
_i /=10;
}
returnstring(bstr);
}
}