Add a simple catch-all implementation of the metadata URI interface (#2029)
* Initial ERC1155 implementation with some tests (#1803) * Initial ERC1155 implementation with some tests * Remove mocked isERC1155TokenReceiver * Revert reason edit nit * Remove parameters associated with isERC1155TokenReceiver call * Add tests for approvals and single transfers * Add tests for transferring to contracts * Add tests for batch transfers * Make expectEvent.inTransaction tests async * Renamed "owner" to "account" and "holder" * Document unspecified balanceOfBatch reversion on zero behavior * Ensure accounts can't set their own operator status * Specify descriptive messages for underflow errors * Bring SafeMath.add calls in line with OZ style * Explicitly prevent _burn on the zero account * Implement batch minting/burning * Refactored operator approval check into isApprovedForAll calls * Renamed ERC1155TokenReceiver to ERC1155Receiver * Added ERC1155Holder * Fix lint issues * Migrate tests to @openzeppelin/test-environment * port ERC1155 to Solidity 0.6 * make ERC1155 constructor more similar to ERC721 one * also migrate mock contracts to Solidity 0.6 * mark all non-view functions as virtual * add simple catch-all implementation for the metadata URI interface * include an internal function to set the URI so users can implement functionality to switch URIs * add tests for ERC1155 metadata URI * fix nits, mostly pointed out by linter * convert ERC1155 metadata URI work to Solidity 0.6 * mark all non-view functions as virtual * Port ERC 1155 branch to Solidity 0.6 (and current master) (#2130) * port ERC1155 to Solidity 0.6 * make ERC1155 constructor more similar to ERC721 one * also migrate mock contracts to Solidity 0.6 * mark all non-view functions as virtual * Update contracts/token/ERC1155/IERC1155MetadataURI.sol Starting on Solidity v0.6.2, interfaces can now inherit. \o/ Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com> * Fix compile errors * Remove URI event * Merge MetadataCatchAll into ERC1155 * Improve documentation. * Simplify tests * Move tests into ERC1155 tests * Update documentation * Bump minimum compiler version for inteface inheritance * Fix holder tests * Improve setUri docs * Fix docs generation Co-authored-by: Alan Lu <alanlu1023@gmail.com> Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com> Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./IERC1155.sol";
|
||||
import "./IERC1155MetadataURI.sol";
|
||||
import "./IERC1155Receiver.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../../utils/Address.sol";
|
||||
@ -15,8 +16,7 @@ import "../../introspection/ERC165.sol";
|
||||
* See https://eips.ethereum.org/EIPS/eip-1155
|
||||
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
|
||||
*/
|
||||
contract ERC1155 is ERC165, IERC1155
|
||||
{
|
||||
contract ERC1155 is ERC165, IERC1155, IERC1155MetadataURI {
|
||||
using SafeMath for uint256;
|
||||
using Address for address;
|
||||
|
||||
@ -26,6 +26,9 @@ contract ERC1155 is ERC165, IERC1155
|
||||
// Mapping from account to operator approvals
|
||||
mapping (address => mapping(address => bool)) private _operatorApprovals;
|
||||
|
||||
// Used as the URI for all token types by relying on ID substition, e.g. https://token-cdn-domain/{id}.json
|
||||
string private _uri;
|
||||
|
||||
/*
|
||||
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
|
||||
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
|
||||
@ -39,9 +42,36 @@ contract ERC1155 is ERC165, IERC1155
|
||||
*/
|
||||
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
|
||||
|
||||
constructor() public {
|
||||
/*
|
||||
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
|
||||
*/
|
||||
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
|
||||
|
||||
/**
|
||||
* @dev See {_setURI}.
|
||||
*/
|
||||
constructor (string memory uri) public {
|
||||
_setURI(uri);
|
||||
|
||||
// register the supported interfaces to conform to ERC1155 via ERC165
|
||||
_registerInterface(_INTERFACE_ID_ERC1155);
|
||||
|
||||
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
|
||||
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev See {IERC1155MetadataURI-uri}.
|
||||
*
|
||||
* This implementation returns the same URI for *all* token types. It relies
|
||||
* on the token type ID substituion mechanism
|
||||
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
|
||||
*
|
||||
* Clients calling this function must replace the `{id}` substring with the
|
||||
* actual token type ID.
|
||||
*/
|
||||
function uri(uint256) external view override returns (string memory) {
|
||||
return _uri;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,6 +225,29 @@ contract ERC1155 is ERC165, IERC1155
|
||||
_doSafeBatchTransferAcceptanceCheck(msg.sender, from, to, ids, values, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets a new URI for all token types, by relying on the token type ID
|
||||
* substituion mechanism
|
||||
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
|
||||
*
|
||||
* By this mechanism, any occurence of the `{id}` substring in either the
|
||||
* URI or any of the values in the JSON file at said URI will be replaced by
|
||||
* clients with the token type ID.
|
||||
*
|
||||
* For example, the `https://token-cdn-domain/{id}.json` URI would be
|
||||
* interpreted by clients as
|
||||
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
|
||||
* for token type ID 0x4cce0.
|
||||
*
|
||||
* See {uri}.
|
||||
*
|
||||
* Because these URIs cannot be meaningfully represented by the {URI} event,
|
||||
* this function emits no events.
|
||||
*/
|
||||
function _setURI(string memory newuri) internal virtual {
|
||||
_uri = newuri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function to mint an amount of a token with the given ID
|
||||
* @param to The address that will own the minted token
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.6.0;
|
||||
pragma solidity ^0.6.2;
|
||||
|
||||
import "../../introspection/IERC165.sol";
|
||||
|
||||
@ -8,7 +8,7 @@ import "../../introspection/IERC165.sol";
|
||||
@title ERC-1155 Multi Token Standard basic interface
|
||||
@dev See https://eips.ethereum.org/EIPS/eip-1155
|
||||
*/
|
||||
abstract contract IERC1155 is IERC165 {
|
||||
interface IERC1155 is IERC165 {
|
||||
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
|
||||
|
||||
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
|
||||
@ -17,15 +17,15 @@ abstract contract IERC1155 is IERC165 {
|
||||
|
||||
event URI(string value, uint256 indexed id);
|
||||
|
||||
function balanceOf(address account, uint256 id) public view virtual returns (uint256);
|
||||
function balanceOf(address account, uint256 id) external view returns (uint256);
|
||||
|
||||
function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual returns (uint256[] memory);
|
||||
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
|
||||
|
||||
function setApprovalForAll(address operator, bool approved) external virtual;
|
||||
function setApprovalForAll(address operator, bool approved) external;
|
||||
|
||||
function isApprovedForAll(address account, address operator) external view virtual returns (bool);
|
||||
function isApprovedForAll(address account, address operator) external view returns (bool);
|
||||
|
||||
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external virtual;
|
||||
function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
|
||||
|
||||
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external virtual;
|
||||
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external;
|
||||
}
|
||||
|
||||
13
contracts/token/ERC1155/IERC1155MetadataURI.sol
Normal file
13
contracts/token/ERC1155/IERC1155MetadataURI.sol
Normal file
@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.6.2;
|
||||
|
||||
import "./IERC1155.sol";
|
||||
|
||||
/**
|
||||
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
|
||||
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
|
||||
*/
|
||||
interface IERC1155MetadataURI is IERC1155 {
|
||||
function uri(uint256 id) external view returns (string memory);
|
||||
}
|
||||
21
contracts/token/ERC1155/README.adoc
Normal file
21
contracts/token/ERC1155/README.adoc
Normal file
@ -0,0 +1,21 @@
|
||||
= ERC 1155
|
||||
|
||||
This set of interfaces and contracts are all related to the https://eips.ethereum.org/EIPS/eip-1155[ERC1155 Multi Token Standard].
|
||||
|
||||
The EIP consists of three interfaces which fulfill different roles, found here as `IERC1155`, `IERC1155MetadataURI` and `IERC1155Receiver`.
|
||||
|
||||
`ERC1155` implement the mandatory `IERC1155` interface, as well as the optional extension `IERC1155MetadataURI` by relying on the substition mechanism to use the same URI for all token types, dramatically reducing gas costs.
|
||||
|
||||
`ERC1155Holder` implements the `IERC1155Receiver` interface for contracts that can receive (and hold) ERC1155 tokens.
|
||||
|
||||
== Core
|
||||
|
||||
{{IERC1155}}
|
||||
|
||||
{{IERC1155MetadataURI}}
|
||||
|
||||
{{ERC1155}}
|
||||
|
||||
{{IERC1155Receiver}}
|
||||
|
||||
{{ERC1155Holder}}
|
||||
@ -1,12 +0,0 @@
|
||||
---
|
||||
sections:
|
||||
- title: Core
|
||||
contracts:
|
||||
- IERC1155
|
||||
- ERC1155
|
||||
- IERC1155Receiver
|
||||
---
|
||||
|
||||
This set of interfaces and contracts are all related to the [ERC1155 Multi Token Standard](https://eips.ethereum.org/EIPS/eip-1155).
|
||||
|
||||
The EIP consists of two interfaces which fulfill different roles, found here as `IERC1155` and `IERC1155Receiver`. Only `IERC1155` is required for a contract to be ERC1155 compliant. The basic functionality is implemented in `ERC1155`.
|
||||
Reference in New Issue
Block a user