Code Monkey home page Code Monkey logo

erc-1155's Introduction

ERC-1155: Semi Fungible Token Standard implementation

This repository maintains a secure, efficient and standards-compliant implementation of the ERC-1155 token standard for Ethereum. The implementation was created during Horizon Blockchain Games' participation in the coauthoring of the ERC-1155 and is used by Skyweaver, Opensea, and many other projects since its release.

The ERC-1155 token standard contains multiple classes of tokens referenced by IDs from non-fungible (max supply=1), to semi-fungible (supply=low), to highly fungible (supply=high). Standard interface discussion at ERC-1155.

Getting started

Install

yarn add @0xsequence/erc-1155 or npm install @0xsequence/erc-1155

Usage

pragma solidity ^0.8.0;

import '@0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155.sol';

contract MyERC1155Token is ERC1155 {
  ...
}

Description

The contracts in this repository follow a standard implementation of an (ERC-1155 contract. This standard provides basic functionality to track and transfer multiple tokens and the interface provide an API other contracts and off-chain third parties can use.

ERC-1155 contracts keep track of many token balances, which can lead to significant efficiency gains when batch transferring multiple token classes simultaneously. This is particularly useful for fungible tokens that are likely to be transfered together, such as gaming items (cards, weapons, parts of objects, minerals, etc.). The possible efficiency gains are more significant if the amount of tokens each address can own is capped, as shown in this implementation examples.

This repository contains two main implementations of the ERC-1155 token standard: ERC1155 and ERC155PackedBalance. The latter implementation packs multiple balances within a single uint256 using bitwise operations. This brings the cost of transferring 100 different token classes to 467,173 gas, an average of 4,671 gas per token type transfer. Still using MT, but without balance packing, transferring 100 different token types costs 2,763,399 gas, an average of 27,633 gas per token transfer. The latter is already an improvement over multiple fungible tokens that are stored on different contracts, since cross-contract calls have a base cost of 700 gas. This is ignoring the cost of initial approvals that would need to be set for each user and existing ERC-20 tokens.

Specification

A detailed specification document can be found at SPECIFICATIONS.md.

Security Review

@0xsequence/erc-1155 has been audited by two independant parties and all issues discovered were addressed.

** Agustín was hired as a full-time employee at Horizon after the audit was completed. Agustín did not take part in the writing of Semi Fungible contracts.

Dev env & release

This repository is configured as a yarn workspace, and has multiple pacakge.json files. Specifically, we have the root ./package.json for the development environment, contract compilation and testing. Contract source code and distribution files are packaged in "src/package.json".

To release a new version, make sure to bump the version, tag it, and run yarn release. The release command will publish the @0xsequence/erc-1155 package in the "src/" folder, separate from the root package. The advantage here is that application developers who consume @0xsequence/erc-1155 aren't required to install any of the devDependencies in their toolchains as our build and contract packages are separated.

LICENSE

Copyright (c) 2017-present Horizon Blockchain Games Inc.

Licensed under Apache-2.0

erc-1155's People

Contributors

acrylix avatar alexanderatallah avatar dependabot[bot] avatar fj avatar ianha avatar phabc avatar pkieltyka avatar screaminghawk avatar xiam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erc-1155's Issues

ERC1155Meta InternalCompilerError

I have been experimenting with implementing the ERC1155 smartcontracts from the NPM module for a custom token. At the moment every time I try to compile an ERC1155Meta.sol implementation I get a compile error:

✖ Compiling contracts with solc 0.5.16 (commit.9c3226ce)
Compilation errors:
InternalCompilerError: Unknown dynamically sized type: struct ERC1155Meta.GasReceipt memory

The same error happens if I try to use the PackedBalance version.
Not sure if this is a noob mistake on my end - my code or dev env, if it's a bug in solidity, or if the ERC1155Meta.GasReceipt definition needs debugging - does anyone else come across this error ??
I'm relatively new to this, first time trying to adapt a smartcontract for my own use case today.

Bug Bounty: Pre-audit

We are currently partnering with Gitcoin to provide bounties for vulnerabilities in our contracts. The rewards are small as these contracts have not yet been audited. The bounties size will be reviewed upward once the audits have been performed.

Contract eligible for bounty

What vulnerabilities should you look for?

We of course want to know every vulnerability, but in particular:

  • Risk of funds being stolen
  • Risk of funds being frozen or lost
  • Risk of invalid balance changes

We follow many of the bug bounty rules that the Ethereum Foundation does:

  • Decisions on the eligibility and size of a reward are the sole discretion of Horizon Games.

  • Public disclosure of a vulnerability makes it ineligible for a bounty. Instead issues must be submitted to [email protected].

  • Issues must be new to the team. They can’t have already been identified by another user or by an audit.

  • No employees, contractors or others with current or prior commercial relationships with Horizon Games are eligible for rewards.

  • Provide the steps required to demonstrate an issue. If we cannot reproduce an issue we will not be able to reward it.

Bounty size

The size of the bounty will vary depending on the severity of the issue discovered. The severity is calculated according to the OWASP risk rating model based on Impact and Likelihood.

Decisions on the eligibility and size of a reward are guided by the rules above, but are, in the end, determined at the sole discretion of Horizon Games

Critical: up to $3,000
High: up to $1,500
Medium: up to $500
Low: up to $250

image

Other considerations

In addition to severity, other variables are also considered when Horizon evaluates the eligibility and size of a bounty, including (but not limited to):

  • Quality of description
    Higher rewards are paid for clear, well-written submissions.

  • Quality of reproducibility
    Please include test code, scripts and detailed instructions. The easier it is for us to reproduce and verify the vulnerability, the higher the reward.

  • Quality of fix, if included
    Higher rewards are paid for submissions with clear description of how to fix the issue.

Link to deployment

Is any of this deployed? Are there any transactions on any networks that can be reviewed?

The Metadata URI extension is missing its signature

According to EIP 1155 Metadata Extensions, the supportsInterface function MUST return true for an interfaceID of 0x0e89341c when the ERC1155Metadata_URI extension is included.

However, the ERC1155MetadataMock.sol contract does not include any constants or support for this interface.

To conform to the spec, users would have to override supportsInterface and return the correct constants.

eip 1178

So we are thinking about supporting ERC-1178 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1178.md for Loom Network games.

Was thinking your batch interface fits nicely into the 1178 standard. Perhaps we can make an official EIP for just the batch methods you have proposed here, that would merge well into erc-1178 or erc-721 tokens.

General Question RE: ERC1155_BATCH_RECEIVED_VALUE

Apologies in advance for the general question in the issues section, but I felt it is a simple enough query to not be a bother.

I wanted to get some help understanding the happy path for the contract recipient check during mint functions:

function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data) internal { // Pass data if recipient is contract if (_to.isContract()) { bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data); require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE"); } }

I am not certain what input in bytes during mint and batchMint would allow me to distribute tokens to a contract address. I do not fully understand how this check works. I can see the set values in the ERC1155.sol contract state variables, but do not know what needs to be input in arguments for an actual mint to pass this check.

Any help would be appreciated :) I am 90% done with an implementation of ERC1155 that borrows from this repository's fantastic framework. Thank you in advance.

don't play well with openzepplin

Thanks for this great library! but updating openzeppelin-solidity to latest 4.0.0 and I can not compile my project

running but outdated combination taken from https://github.com/ProjectOpenSea/opensea-erc1155

    "multi-token-standard": "github:ProjectOpenSea/multi-token-standard",
    "openzeppelin-solidity": "^2.1.3",

How to reproduce, upgrading 3rd parties

openzeppelin-solidity 4.0.0    // use pragma solidity ^0.8.0;
@0xsequence/erc-1155 3.0.4    // use use pragma solidity ^0.7.4;

Tried both

    solc: {
      version: "^0.8.0",
    },

,ParserError: Source file requires different compiler version (current compiler is 0.8.3+commit.8d00100c.Emscripten.clang) - note that nightly builds are considered to be strictly less than
the released version
 --> @0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155MintBurn.sol:2:1:
  |
2 | pragma solidity 0.7.4;

or

    solc: {
      version: "^0.7.4",
    },

,ParserError: Source file requires different compiler version (current compiler is 0.8.3+commit.8d00100c.Emscripten.clang) - note that nightly builds are considered to be strictly less than
the released version
 --> @0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155MintBurn.sol:2:1:
  |
2 | pragma solidity 0.7.4;

what do you recommend? rollbacking openzeppelin-solidity to a previous version? hoping that I find one which stilluse Solc 0.7 branch?

How do you check the owner of the token?

I can see that in ERC1155.sol , we get the balances by passing in the address and tokenId.

  // Objects balances
  mapping (address => mapping(uint256 => uint256)) internal balances;

However, how can I check the owner of a token without knowing the address of the owner?

Cheers.

Empty Migration Folder and Deployment?

I'm new to blockchain development and having been learning how to use solidity, truffle, ether.js and the like.

I am curious as to how you would deploy the contracts to a local Ganache instance, as your migrations folder is empty (only .none file) for truffle to do the migration?

Any help in the right direction would be appreciated...

not found when trying to import Ownable

I'm trying to import Ownable.sol as follows:

import "@0xsequence/erc-1155/contracts/utils/Ownable.sol";

But I'm getting this error:

project:/contracts/ERC1155Tradeable.sol:2:1: ParserError: Source "@0xsequence/erc-1155/contracts/contracts/utils/Ownable.sol" not found: File import callback not supported
import "@0xsequence/erc-1155/contracts/contracts/utils/Ownable.sol";

How to fix this?

Update to Solidity 0.6.0

Contracts wouldn't compile with solidity compiler set to 0.6.0 and up. Please provide update, since npm package cannot be used as dependency for newer applications.

Thank you very much

General Questions on ERC-1155 uses and the _id value.

Hi there,

I came across these contracts while researching NFT standards and wanted to ask or at least firm up my understanding of a few things regarding the differences/capabilities of the standard and these contracts in general.

I'm really sorry if this isn't the best place to do this, I have found it incredibly hard on discord or other forums to get straight answers to a few of these and if the answers can add value elsewhere to future users I would love to collate them into some kind of tutorial/wiki that goes beyond the naive implementations we see out in the wild.

Minting a token - Happy Path

As we see generally minting a token in an ERC1155 will give you back an id. (0x01) lets say. So this is ID of one type of contract and a qty of 1.

In this case I can have multiples minted of ID=0x01 and these can be assigned to multiple addresses?

Minting a token - single item per ID

How then to only have one ID=0x01 NFT issues? These are preminted with a total of 1?

Minting tokens - Where we have some uniqueness

I have seen some NFT examples where they place some constants in the contract to describe the ID types (card types for example, special, legendary etc). This would be good if all those cards were idempotent/similar stats/details so the ID resolves to a common JSON metadata file they all share.

What then if you wanted to say:

  1. Have some uniqueness in the stats off chain?
  2. Have some uniqueness in the stats on chain?

In this I mean, perhaps you generate a class of card (special card10) and then you have some element of random stats given to that card (XP boosts etc). At this point I think you are going to have to create a unique ID for each and every card in your universe?

Now the ID space is a 64 bit hex number so there are plenty in there so I think that would fine.

Would any issues come using such large numbers when packing and sending them onto other addresses or is the O(1) lookup and searching happening in the code here? There is no time costs to larger and larger IDs?

In the case of stats on chain, how best to store that? Say you wanted to store 4-6 values on the NFT on chain for some use in a smart contract in such a way the JSON metadata is not a possibility? Would you store that in the same NFT as an array to ID mapping or would you embed it in the ID using some kind of bitwise shift? (Top 3/4 of the ID are the monotonically incrementing ID counter and the bottom 1/4 is the array of stats in 4byte blocks or something).

summary

I hope these questions make sense, I'm trying to understand how the universe of NFTs can be generated and stored, any performance considerations along side using them.

And also, some on-chain data storage for pertinent data that we would like to have on-chain attached to an NFT, how best would that be achieved in a clear and concise manner that isn't too costly.

Thanks again for your time and building this amazing EIP.

I need help!

I'm a green hand,Can you provide some demos?Preferably out of the box
thx

The uri function documentation should not indicate hex format IDs

I think the documentation for the ERC1155Metadata contracts uri() function is misleading:

https://github.com/arcadeum/multi-token-standard/blob/36ebad2194d79f3cf510fcaa80738d61344ff9ab/contracts/tokens/ERC1155/ERC1155Metadata.sol#L23

At first glance, this reads like the function will return the URL with an alphanumeric hexadecimal string representation of the token ID (i.e., "hex format"), rather than a string representation of the integer, which is what _uint2str() does.

It uses the word "assumed" but whose assumption is this? The spec does allow clients to assume a lowercase alphanumeric hexadecimal representation of the token ID when the contracts returns an {id} placeholder, but that's not what is happening here.

How do you check if the token is unique?

I was trying to implement the mint and mintBatch functions, but I don't know how to ensure that tokens are unique (NFT). Is it based from the balance of the owners?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.