All Projects → iamdefinitelyahuman → nftoken

iamdefinitelyahuman / nftoken

Licence: MIT license
A non-fungible implementation of the ERC20 standard, allowing scalable NFT transfers with fixed gas costs.

Programming Languages

solidity
1140 projects
Dockerfile
14818 projects

Projects that are alternatives of or similar to nftoken

token-allowance-checker
Control ERC20 token approvals
Stars: ✭ 72 (+22.03%)
Mutual labels:  erc20
ERC884-reference-implementation
An Interface and Reference Implementation of the ERC-884 DGCL Token.
Stars: ✭ 42 (-28.81%)
Mutual labels:  erc20
erc1363-payable-token
Code implementation for the ERC-1363 Payable Token
Stars: ✭ 83 (+40.68%)
Mutual labels:  erc20
BatchPayments
A gas conscious batch payment implementation
Stars: ✭ 27 (-54.24%)
Mutual labels:  erc20
go-dc-wallet
交易所收提币功能
Stars: ✭ 76 (+28.81%)
Mutual labels:  erc20
eos21
Teleport your ERC20 tokens to EOS.
Stars: ✭ 42 (-28.81%)
Mutual labels:  erc20
tokenbridge
A bidirectional Ethereum / RSK Token Bridge implementation.
Stars: ✭ 85 (+44.07%)
Mutual labels:  erc20
cindicator tokensale
Contracts for Cindicator ICO
Stars: ✭ 14 (-76.27%)
Mutual labels:  erc20
0x-codesandbox
0x Codesandbox
Stars: ✭ 14 (-76.27%)
Mutual labels:  erc20
ape
The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals
Stars: ✭ 339 (+474.58%)
Mutual labels:  brownie
ape-safe
gnosis safe tx builder
Stars: ✭ 211 (+257.63%)
Mutual labels:  brownie
brownie simple storage
No description or website provided.
Stars: ✭ 22 (-62.71%)
Mutual labels:  brownie
niftygate
Drop-in Access Control via NFT Ownership
Stars: ✭ 61 (+3.39%)
Mutual labels:  erc20
erc20-balance
💎 Get 2000+ ERC-20 token balances with JavaScript. Supports Node.js and Deno
Stars: ✭ 18 (-69.49%)
Mutual labels:  erc20
cryptowallet-cli
CW is a crypto wallet generator CLI tool for a lot of blockchains: Bitcoin, Ethereum, Binance Smart Chain and many others
Stars: ✭ 45 (-23.73%)
Mutual labels:  erc20
koinos-gui-miner
The Koinos Miner (GUI) provides a sleek and functional user interface that allows users to mine the KOIN ERC-20 which will be used to deliver an equitable initial token distribution on the Koinos blockchain.
Stars: ✭ 26 (-55.93%)
Mutual labels:  erc20
ethereum-kit-ios
Comprehensive EVM SDK (ex: Ethereum, Binance Smart Chain) for iOS, implemented on Swift. Create wallets, watch wallets (read-only), sync transactions, filter transactions by type (erc20, bep20, swap transactions etc.), swap using native DEX protocols, easily extendable to work with custom smart contracts, and full support for EIP1159.
Stars: ✭ 148 (+150.85%)
Mutual labels:  erc20
bnbridge.exchange
https://bnbridge.exchange
Stars: ✭ 43 (-27.12%)
Mutual labels:  erc20
nftfy-v1-core
A decentralized protocol for NFT fractionalization
Stars: ✭ 62 (+5.08%)
Mutual labels:  erc20
openst-platform
OpenST Platform provides an interface to tokenise mainstream consumer applications with crypto-assets on Ethereum [deprecated in favour of openst.js and mosaic.js]
Stars: ✭ 84 (+42.37%)
Mutual labels:  erc20

NFToken

NFToken is a non-fungible implementation of the ERC20 standard, allowing scalable NFT transfers with fixed gas costs.

Motivations

NFToken is inspired by discussions with Gabriel Shapiro about the legal benefits and technical challenges of representing certificated shares on the Ethereum blockchain. See his excellent article "Tokenizing Corporate Capital Stock" for more information on this subject.

The goal in building NFToken was to create a token that is transferable like an ERC20, allows anyone to verify the complete chain of custody for any given token, and does not have prohibitively high gas costs for large transfers.

The implementation in this repository is a minimal proof of concept that can serve as a starting point for those who wish to expand upon these ideas and integrate them within their own projects. We have also produced an expanded version as an integral component of the ZeroLaw Augmentation Protocol (ZAP), that allows unique attributes to be applied on a per-token basis.

How it Works

NFToken applies a unique, sequential index value to every token. The first token minted will have an index value of 1. The maximum index value is 18446744073709551616 (2^64-2). References to token ranges are in the format start:stop where the final included value is stop-1. For example, a range of 2:6 would contains tokens 2, 3, 4 and 5.

Rather than storing every individual ID number, the contract only records the end of each token range. It takes advantage of the lack of cost in declaring empty storage, and saves range data in long fixed-length arrays.

Each transfer of tokens will include one or more TransferRange events. Monitoring this event allows you to track the chain of custody for each token.

Gas Costs

The upper bound cost to mint is ~500,000 gas. This mints 2^64-2 tokens - the maximum totalSupply for the contract.

The upper bound gas cost to transfer a single range is ~86,000 gas for the first range, and ~38,000 for each additional range. With a maximally fragmented token range, transferring one hundred tokens with a single token per range will cost ~39,000 gas per token.

However, transfer costs remain consistent regardless of the size of the range. This means the absolute lower bound cost, transferring 2^64-2 tokens as a single range, is ~0.00000000145 gas per token. A more reasonable lower bound, transferring one hundred tokens within a single range, costs ~860 gas per token.

The contract will merge ranges whenever possible, however fragmentation is inevitable and over time transfer costs are expected to increase. There are likely further optimizations that can be performed on this code to decrease costs and reduce the rate of fragmentation. If you have any ideas, I would love to hear from you.

Interface

NFToken fully implements the ERC20 interface and adheres to all expected behaviours. It also includes additional methods for working with token ranges, minting, and burning.

Working with Token Ranges

Tokens may be transferred via the standard ERC20 transfer and transferFrom methods, however if calling these methods there is no guarantee which specific tokens will be sent. The transferRange method allows a user to select exactly which tokens to transfer.

The following methods are available for accessing range data and initiating transfers:

rangesOf

function rangesOf(address _owner) external view returns (uint64[2][] memory)

Getter method that returns the start:stop indexes of each token range belonging to _owner.

>>> nft.rangesOf(accounts[1])
((1, 1000), (2000, 10001))

getRange

function getRange(uint256 _idx) external view returns (address _owner, uint64 _start, uint64 _stop)

Getter method that returns information about the range contains token _idx.

>>> token.getRange(31337).dict()
{
    '_owner': "0xf414d65808f5f59aE156E51B97f98094888e7d92",
    '_start': 30000,
    '_stop': 35001,
}

transferRange

function transferRange(address _to, uint64 _start, uint64 _stop) external returns (bool)

Transfers the token range _start:_stop from msg.sender to _to. Transferring a partial range is allowed. Transferring tokens from multiple ranges in the same call is not.

All transfers will emit one Transfer and one or more TransferRange events.

>>> nft.rangesOf(accounts[1])
((1, 1000), (2000, 10001))
>>> nft.transferRange(accounts[2], 3333, 4242, {'from': accounts[1]})
Transaction sent: 0x9ae3c41984aad767b2a535a5ade8f70b104b125da622124e9c3be52b7e373a11
NFToken.transferRange confirmed - block: 4   gas used: 134829 (100.00%)

>>> nft.rangesOf(accounts[1])
((1, 1000), (2000, 3333), (4242, 10001))

Minting and Burning

NFTokenMintable inherits NFToken, and includes functionality for minting and burning tokens.

mint

function mint(address _target, uint64 _value) external returns (bool)

Mints _value new tokens that are owned by _target.

>>> nft.rangesOf(accounts[0])
((1, 1001),)
>>> nft.mint(accounts[0], 5000, {'from': accounts[0]})
Transaction sent: 0x77ec76224d90763641971cd61e99711c911828053612cc16eb2e5d7faa20815e
NFToken.mint confirmed - block: 3   gas used: 182038 (100.00%)

>>> nft.rangesOf(accounts[0])
((1, 6001),)

burn

function burn(uint64 _start, uint64 _stop) external returns (bool)

Burns the tokens within the range _start:_stop. Only the contract owner can call to burn, and only tokens belonging to the owner can be burned.

>>> nft.burn(accounts[0], 42, 1337, {'from': accounts[0]})
Transaction sent: 0x5414b31e3e44e657ed5ee04c0c6e4c673ab2c6300f392dfd7c282b348db0bbc7
NFToken.burn confirmed - block: 6   gas used: 48312 (100.00%)

>>> nft.rangesOf(accounts[0])
((1, 42), (1337, 6001))

Testing

Unit testing and deployment of this project is performed with Brownie.

To run the tests:

brownie test

A dockerfile is available if you are experiencing issues.

License

This project is licensed under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].