Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs #2168

Merged
merged 4 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions contracts/token/ERC20/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,40 @@

This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-20[ERC20 Token Standard].

TIP: For an overview of ERC20 tokens and a walkthrough on how to create a token contract read our xref:ROOT:tokens.adoc#ERC20[ERC20 guide].
TIP: For an overview of ERC20 tokens and a walkthrough on how to create a token contract read our xref:ROOT:erc20.adoc[ERC20 guide].

There a few core contracts that implement the behavior specified in the EIP:

* {IERC20}: the interface all ERC20 implementations should conform to
* {ERC20}: the base implementation of the ERC20 interface
* {ERC20Detailed}: includes the <<ERC20Detailed-name,`name`>>,
<<ERC20Detailed-symbol,`symbol`>> and <<ERC20Detailed-decimals,`decimals`>>
optional standard extension to the base interface
* {IERC20}: the interface all ERC20 implementations should conform to.
* {ERC20}: the implementation of the ERC20 interface, including the <<ERC20-name,`name`>>, <<ERC20-symbol,`symbol`>> and <<ERC20-decimals,`decimals`>> optional standard extension to the base interface.

Additionally there are multiple custom extensions, including:

* designation of addresses that can create token supply ({ERC20Mintable}), with an optional maximum cap ({ERC20Capped})
* destruction of own tokens ({ERC20Burnable})
* designation of addresses that can pause token operations for all users ({ERC20Pausable}).
* designation of addresses that can pause token transfers for all users ({ERC20Pausable}).
* efficient storage of past token balances to be later queried at any point in time ({ERC20Snapshot}).
* destruction of own tokens ({ERC20Burnable}).
* enforcement of a cap to the total supply when minting tokens ({ERC20Capped}).

Finally, there are some utilities to interact with ERC20 contracts in various ways.

* {SafeERC20} is a wrapper around the interface that eliminates the need to handle boolean return values.
* {TokenTimelock} can hold tokens for a beneficiary until a specified time.

NOTE: This page is incomplete. We're working to improve it for the next release. Stay tuned!

== Core

{{IERC20}}

{{ERC20}}

{{ERC20Detailed}}

== Extensions

{{ERC20Mintable}}

{{ERC20Burnable}}
{{ERC20Snapshot}}

{{ERC20Pausable}}

{{ERC20Capped}}
{{ERC20Burnable}}

{{ERC20Snapshot}}
{{ERC20Capped}}

== Utilities

Expand Down
31 changes: 7 additions & 24 deletions contracts/token/ERC721/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,37 @@

This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-721[ERC721 Non-Fungible Token Standard].

TIP: For a walkthrough on how to create an ERC721 token read our xref:ROOT:tokens.adoc#ERC721[ERC721 guide].
TIP: For a walkthrough on how to create an ERC721 token read our xref:ROOT:erc721.adoc[ERC721 guide].

The EIP consists of three interfaces, found here as {IERC721}, {IERC721Metadata}, and {IERC721Enumerable}. Only the first one is required in a contract to be ERC721 compliant.

Each interface is implemented separately in {ERC721}, {ERC721Metadata}, and {ERC721Enumerable}. You can choose the subset of functionality you would like to support in your token by combining the
desired subset through inheritance.

The fully featured token implementing all three interfaces is prepackaged as {ERC721Full}.
The EIP consists of three interfaces, found here as {IERC721}, {IERC721Metadata}, and {IERC721Enumerable}. Only the first one is required in a contract to be ERC721 compliant. However, all three are implemented in {ERC721}.

Additionally, {IERC721Receiver} can be used to prevent tokens from becoming forever locked in contracts. Imagine sending an in-game item to an exchange address that can't send it back!. When using <<IERC721-safeTransferFrom,`safeTransferFrom`>>, the token contract checks to see that the receiver is an {IERC721Receiver}, which implies that it knows how to handle {ERC721} tokens. If you're writing a contract that needs to receive {ERC721} tokens, you'll want to include this interface.

Finally, some custom extensions are also included:

* {ERC721Mintable} — like the ERC20 version, this allows certain addresses to mint new tokens
* {ERC721Pausable} — like the ERC20 version, this allows addresses to freeze transfers of tokens
Additionally there are multiple custom extensions, including:

NOTE: This page is incomplete. We're working to improve it for the next release. Stay tuned!
* designation of addresses that can pause token transfers for all users ({ERC721Pausable}).
* destruction of own tokens ({ERC721Burnable}).

== Core

{{IERC721}}

{{ERC721}}

{{IERC721Metadata}}

{{ERC721Metadata}}

{{ERC721Enumerable}}

{{IERC721Enumerable}}

{{IERC721Full}}

{{ERC721Full}}
{{ERC721}}

{{IERC721Receiver}}

== Extensions

{{ERC721Mintable}}

{{ERC721MetadataMintable}}
{{ERC721Pausable}}

{{ERC721Burnable}}

{{ERC721Pausable}}

== Convenience

{{ERC721Holder}}
2 changes: 1 addition & 1 deletion contracts/token/ERC777/README.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= ERC 777
This set of interfaces and contracts are all related to the [ERC777 token standard](https://eips.ethereum.org/EIPS/eip-777).

TIP: For an overview of ERC777 tokens and a walkthrough on how to create a token contract read our xref:ROOT:tokens.adoc#ERC777[ERC777 guide].
TIP: For an overview of ERC777 tokens and a walkthrough on how to create a token contract read our xref:ROOT:erc777.adoc[ERC777 guide].

The token behavior itself is implemented in the core contracts: {IERC777}, {ERC777}.

Expand Down
2 changes: 2 additions & 0 deletions contracts/utils/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Miscellaneous contracts containing utility functions, often related to working w

{{EnumerableSet}}

{{EnumerableMap}}

{{Create2}}

{{ReentrancyGuard}}
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/access-control.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ OpenZeppelin provides xref:api:access.adoc#Ownable[`Ownable`] for implementing o

[source,solidity]
----
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/access/Ownable.sol";

Expand Down Expand Up @@ -140,7 +140,7 @@ contract MyToken is ERC20, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

constructor() public {
constructor() ERC20("MyToken", "TKN") public {
// Grant the contract deployer the default admin role: it will be able
// to grant and revoke any roles
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
Expand Down
10 changes: 6 additions & 4 deletions docs/modules/ROOT/pages/erc20-supply.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ As we can see, `_mint` makes it super easy to do this correctly.
[[modularizing-the-mechanism]]
== Modularizing the Mechanism

There is one supply mechanism already included in Contracts: xref:api:token/ERC20.adoc#ERC20Mintable[`ERC20Mintable`]. This is a generic mechanism in which a set of accounts is assigned the `minter` role, granting them the permission to call a xref:api:token/ERC20.adoc#ERC20Mintable-mint-address-uint256-[`mint`] function, an external version of `_mint`.
There is one supply mechanism already included in Contracts: `ERC20DeployReady`. This is a generic mechanism in which a set of accounts is assigned the `minter` role, granting them the permission to call a `mint` function, an external version of `_mint`.

This can be used for centralized minting, where an externally owned account (i.e. someone with a pair of cryptographic keys) decides how much supply to create and to whom. There are very legitimate use cases for this mechanism, such as https://medium.com/reserve-currency/why-another-stablecoin-866f774afede#3aea[traditional asset-backed stablecoins].

Expand All @@ -64,9 +64,9 @@ The accounts with the minter role don't need to be externally owned, though, and
[source,solidity]
----
contract MinerRewardMinter {
ERC20Mintable _token;
ERC20DeployReady _token;

constructor(ERC20Mintable token) public {
constructor(ERC20DeployReady token) public {
_token = token;
}

Expand All @@ -76,7 +76,9 @@ contract MinerRewardMinter {
}
----

This contract, when initialized with an `ERC20Mintable` instance, will result in exactly the same behavior implemented in the previous section. What is interesting about using `ERC20Mintable` is that we can easily combine multiple supply mechanisms by assigning the role to multiple contracts, and moreover that we can do this dynamically.
This contract, when initialized with an `ERC20DeployReady` instance, will result in exactly the same behavior implemented in the previous section. What is interesting about using `ERC20DeployReady` is that we can easily combine multiple supply mechanisms by assigning the role to multiple contracts, and moreover that we can do this dynamically.

TIP: To learn more about roles and permissioned systems, head to our xref:access-control.adoc[Access Control guide].

[[automating-the-reward]]
== Automating the Reward
Expand Down
13 changes: 7 additions & 6 deletions docs/modules/ROOT/pages/erc20.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@ Here's what our GLD token might look like.

[source,solidity]
----
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";

contract GLDToken is ERC20, ERC20Detailed {
constructor(uint256 initialSupply) ERC20Detailed("Gold", "GLD", 18) public {
contract GLDToken is ERC20 {
constructor(uint256 initialSupply) ERC20("Gold", "GLD") public {
_mint(msg.sender, initialSupply);
}
}
----

Our contracts are often used via https://solidity.readthedocs.io/en/latest/contracts.html#inheritance[inheritance], and here we're reusing xref:api:token/ERC20.adoc#erc20[`ERC20`] for the basic standard implementation and xref:api:token/ERC20.adoc#ERC20Detailed[`ERC20Detailed`] to get the xref:api:token/ERC20.adoc#ERC20Detailed-name--[`name`], xref:api:token/ERC20.adoc#ERC20Detailed-symbol--[`symbol`], and xref:api:token/ERC20.adoc#ERC20Detailed-decimals--[`decimals`] properties. Additionally, we're creating an `initialSupply` of tokens, which will be assigned to the address that deploys the contract.
Our contracts are often used via https://solidity.readthedocs.io/en/latest/contracts.html#inheritance[inheritance], and here we're reusing xref:api:token/ERC20.adoc#erc20[`ERC20`] for both the basic standard implementation and the xref:api:token/ERC20.adoc#ERC20-name--[`name`], xref:api:token/ERC20.adoc#ERC20-symbol--[`symbol`], and xref:api:token/ERC20.adoc#ERC20-decimals--[`decimals`] optional extensions. Additionally, we're creating an `initialSupply` of tokens, which will be assigned to the address that deploys the contract.

TIP: For a more complete discussion of ERC20 supply mechanisms, see xref:erc20-supply.adoc[Creating ERC20 Supply].

Expand Down Expand Up @@ -53,14 +52,16 @@ We can also xref:api:token/ERC20.adoc#IERC20-transfer-address-uint256-[transfer]

Often, you'll want to be able to divide your tokens into arbitrary amounts: say, if you own `5 GLD`, you may want to send `1.5 GLD` to a friend, and keep `3.5 GLD` to yourself. Unfortunately, Solidity and the EVM do not support this behavior: only integer (whole) numbers can be used, which poses an issue. You may send `1` or `2` tokens, but not `1.5`.

To work around this, xref:api:token/ERC20.adoc#ERC20Detailed[`ERC20Detailed`] provides a xref:api:token/ERC20.adoc#ERC20Detailed-decimals--[`decimals`] field, which is used to specify how many decimal places a token has. To be able to transfer `1.5 GLD`, `decimals` must be at least `1`, since that number has a single decimal place.
To work around this, xref:api:token/ERC20.adoc#ERC20[`ERC20`] provides a xref:api:token/ERC20.adoc#ERC20-decimals--[`decimals`] field, which is used to specify how many decimal places a token has. To be able to transfer `1.5 GLD`, `decimals` must be at least `1`, since that number has a single decimal place.

How can this be achieved? It's actually very simple: a token contract can use larger integer values, so that a balance of `50` will represent `5 GLD`, a transfer of `15` will correspond to `1.5 GLD` being sent, and so on.

It is important to understand that `decimals` is _only used for display purposes_. All arithmetic inside the contract is still performed on integers, and it is the different user interfaces (wallets, exchanges, etc.) that must adjust the displayed values according to `decimals`. The total token supply and balance of each account are not specified in `GLD`: you need to divide by `10^decimals` to get the actual `GLD` amount.

You'll probably want to use a `decimals` value of `18`, just like Ether and most ERC20 token contracts in use, unless you have a very special reason not to. When minting tokens or transferring them around, you will be actually sending the number `num GLD * 10^decimals`.

NOTE: By default, `ERC20` uses a value of `18` for `decimals`. To use a different value, you will need to call xref:api:token/ERC20.adoc#ERC20-_setupDecimals-uint8-[_setupDecimals] in your constructor.

So if you want to send `5` tokens using a token contract with 18 decimals, the the method to call will actually be:

```solidity
Expand Down
10 changes: 5 additions & 5 deletions docs/modules/ROOT/pages/erc721.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ Here's what a contract for tokenized items might look like:

[source,solidity]
----
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract GameItem is ERC721Full {
contract GameItem is ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;

constructor() ERC721Full("GameItem", "ITM") public {
constructor() ERC721("GameItem", "ITM") public {
}

function awardItem(address player, string memory tokenURI) public returns (uint256) {
Expand All @@ -36,7 +36,7 @@ contract GameItem is ERC721Full {
}
----

The xref:api:token/ERC721.adoc#ERC721Full[`ERC721Full`] contract includes all standard extensions, and is probably the one you want to use. In particular, it includes xref:api:token/ERC721.adoc#ERC721Metadata[`ERC721Metadata`], which provides the xref:api:token/ERC721.adoc#ERC721Metadata-_setTokenURI-uint256-string-[`_setTokenURI`] method we use to store an item's metadata.
The xref:api:token/ERC721.adoc#ERC721[`ERC721`] contract includes all standard extensions (xref:api:token/ERC721.adoc#IERC721Metadata[`IERC721Metadata`] and xref:api:token/ERC721.adoc#IERC721Enumerable[`IERC721Enumerable`]). That's where the xref:api:token/ERC721.adoc#ERC721-_setTokenURI-uint256-string-[`_setTokenURI`] method comes from: we use it to store an item's metadata.

Also note that, unlike ERC20, ERC721 lacks a `decimals` field, since each token is distinct and cannot be partitioned.

Expand Down
11 changes: 8 additions & 3 deletions docs/modules/ROOT/pages/gsn-strategies.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,22 @@ NOTE: Always use `_preRelayedCall` and `_postRelayedCall` functions. Internal `

=== How to Use `GSNRecipientERC20Fee`

Your GSN recipient contract needs to inherit from `GSNRecipientERC20Fee` along with appropriate xref:access-control.adoc[access control] (for token minting), set the token details in the constructor of `GSNRecipientERC20Fee` and create a public `mint` function suitably protected by your chosen access control as per the following sample code (which uses the xref:api:access.adoc#MinterRole[MinterRole]):
Your GSN recipient contract needs to inherit from `GSNRecipientERC20Fee` along with appropriate xref:access-control.adoc[access control] (for token minting), set the token details in the constructor of `GSNRecipientERC20Fee` and create a public `mint` function suitably protected by your chosen access control as per the following sample code (which uses xref:api:access.adoc#AccessControl[``AccessControl`]):

[source,solidity]
----
import "@openzeppelin/contracts/GSN/GSNRecipientERC20Fee";
import "@openzeppelin/contracts/access/AccessControl";

contract MyContract is GSNRecipientERC20Fee, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

contract MyContract is GSNRecipientERC20Fee, MinterRole {
constructor() public GSNRecipientERC20Fee("FeeToken", "FEE") {
_setupRole(MINTER_ROLE, _msgSender());_
}

function mint(address account, uint256 amount) public onlyMinter {
function mint(address account, uint256 amount) public {
require(hasRole(MINTER_ROLE, _msgSender()));
_mint(account, amount);
}
}
Expand Down
9 changes: 4 additions & 5 deletions docs/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ Once installed, you can use the contracts in the library by importing them:

[source,solidity]
----
pragma solidity ^0.5.0;
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC721/ERC721Full.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721Mintable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyNFT is ERC721Full, ERC721Mintable {
constructor() ERC721Full("MyNFT", "MNFT") public {
contract MyNFT is ERC721 {
constructor() ERC721("MyNFT", "MNFT") public {
}
}
----
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/utilities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ If you want to Escrow some funds, check out xref:api:payment.adoc#Escrow[`Escrow
[[collections]]
== Collections

If you need support for more powerful collections than Solidity's native arrays and mappings, take a look at xref:api:utils.adoc#EnumerableSet[`EnumerableSet`]. It is similar to a mapping in that it stores and removes elements in constant time and doesn't allow for repeated entries, but it also supports _enumeration_, which means you can easily query all elements of the set both on and off-chain.
If you need support for more powerful collections than Solidity's native arrays and mappings, take a look at xref:api:utils.adoc#EnumerableSet[`EnumerableSet`] and xref:api:utils.adoc#EnumerableMap[`EnumerableMap`]. They are similar to mappings in that they store and remove elements in constant time and don't allow for repeated entries, but they also supports _enumeration_, which means you can easily query all stored entries both on and off-chain.

[[misc]]
== Misc
Expand Down