Update docs
This commit is contained in:
@ -24,7 +24,7 @@ WARNING: Removing the owner altogether will mean that administrative tasks that
|
||||
|
||||
Ownable is a simple and effective way to implement access control, but you should be mindful of the dangers associated with transferring the ownership to an incorrect account that can't interact with this contract anymore. An alternative to this problem is using xref:api:access.adoc#Ownable2Step[`Ownable2Step`]; a variant of Ownable that requires the new owner to explicitly accept the ownership transfer by calling xref:api:access.adoc#Ownable2Step-acceptOwnership--[`acceptOwnership`].
|
||||
|
||||
Note that *a contract can also be the owner of another one*! This opens the door to using, for example, a https://gnosis-safe.io[Gnosis Safe], an https://aragon.org[Aragon DAO], or a totally custom contract that _you_ create.
|
||||
Note that *a contract can also be the owner of another one*! This opens the door to using, for example, a https://safe.global[Gnosis Safe], an https://aragon.org[Aragon DAO], or a totally custom contract that _you_ create.
|
||||
|
||||
In this way, you can use _composability_ to add additional layers of access control complexity to your contracts. Instead of having a single regular Ethereum account (Externally Owned Account, or EOA) as the owner, you could use a 2-of-3 multisig run by your project leads, for example. Prominent projects in the space, such as https://makerdao.com[MakerDAO], use systems similar to this one.
|
||||
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
= Crowdsales
|
||||
|
||||
All crowdsale-related contracts were removed from the OpenZeppelin Contracts library on the https://forum.openzeppelin.com/t/openzeppelin-contracts-v3-0-beta-release/2256[v3.0.0 release] due to both a decline in their usage and the complexity associated with migrating them to Solidity v0.6.
|
||||
|
||||
They are however still available on the v2.5 release of OpenZeppelin Contracts, which you can install by running:
|
||||
|
||||
```console
|
||||
$ npm install @openzeppelin/contracts@v2.5
|
||||
```
|
||||
|
||||
Refer to the https://docs.openzeppelin.com/contracts/2.x/crowdsales[v2.x documentation] when working with them.
|
||||
@ -1,19 +0,0 @@
|
||||
= Drafts
|
||||
|
||||
All draft contracts were either moved into a different directory or removed from the OpenZeppelin Contracts library on the https://forum.openzeppelin.com/t/openzeppelin-contracts-v3-0-beta-release/2256[v3.0.0 release].
|
||||
|
||||
* `ERC20Migrator`: removed.
|
||||
* xref:api:token/ERC20.adoc#ERC20Snapshot[`ERC20Snapshot`]: moved to `token/ERC20`.
|
||||
* `ERC20Detailed` and `ERC1046`: removed.
|
||||
* `TokenVesting`: removed. Pending a replacement that is being discussed in https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1214[`#1214`].
|
||||
* xref:api:utils.adoc#Counters[`Counters`]: moved to xref:api:utils.adoc[`utils`].
|
||||
* xref:api:utils.adoc#Strings[`Strings`]: moved to xref:api:utils.adoc[`utils`].
|
||||
* xref:api:utils.adoc#SignedSafeMath[`SignedSafeMath`]: moved to xref:api:utils.adoc[`utils`].
|
||||
|
||||
Removed contracts are still available on the v2.5 release of OpenZeppelin Contracts, which you can install by running:
|
||||
|
||||
```console
|
||||
$ npm install @openzeppelin/contracts@v2.5
|
||||
```
|
||||
|
||||
Refer to the xref:2.x@contracts:api:drafts.adoc[v2.x documentation] when working with them.
|
||||
@ -106,7 +106,7 @@ A key difference when using xref:api:token/ERC1155.adoc#IERC1155-safeTransferFro
|
||||
ERC1155InvalidReceiver("<ADDRESS>")
|
||||
----
|
||||
|
||||
This is a good thing! It means that the recipient contract has not registered itself as aware of the ERC-1155 protocol, so transfers to it are disabled to *prevent tokens from being locked forever*. As an example, https://etherscan.io/token/0xa74476443119A942dE498590Fe1f2454d7D4aC0d?a=0xa74476443119A942dE498590Fe1f2454d7D4aC0d[the Golem contract currently holds over 350k `GNT` tokens], worth multiple tens of thousands of dollars, and lacks methods to get them out of there. This has happened to virtually every ERC20-backed project, usually due to user error.
|
||||
This is a good thing! It means that the recipient contract has not registered itself as aware of the ERC-1155 protocol, so transfers to it are disabled to *prevent tokens from being locked forever*. As an example, https://etherscan.io/token/0xa74476443119A942dE498590Fe1f2454d7D4aC0d?a=0xa74476443119A942dE498590Fe1f2454d7D4aC0d[the Golem contract currently holds over 350k `GNT` tokens], and lacks methods to get them out of there. This has happened to virtually every ERC20-backed project, usually due to user error.
|
||||
|
||||
In order for our contract to receive ERC-1155 tokens we can inherit from the convenience contract xref:api:token/ERC1155.adoc#ERC1155Holder[`ERC1155Holder`] which handles the registering for us. However, we need to remember to implement functionality to allow tokens to be transferred out of our contract:
|
||||
|
||||
|
||||
@ -68,4 +68,4 @@ include::api:example$ERC20WithAutoMinerReward.sol[]
|
||||
[[wrapping-up]]
|
||||
== Wrapping Up
|
||||
|
||||
We've seen how to implement a ERC-20 supply mechanism: internally through `_mint`. Hopefully this has helped you understand how to use OpenZeppelin Contracts and some of the design principles behind it, and you can apply them to your own smart contracts.
|
||||
We've seen how to implement an ERC-20 supply mechanism: internally through `_mint`. Hopefully this has helped you understand how to use OpenZeppelin Contracts and some of the design principles behind it, and you can apply them to your own smart contracts.
|
||||
|
||||
47
docs/modules/ROOT/pages/erc6909.adoc
Normal file
47
docs/modules/ROOT/pages/erc6909.adoc
Normal file
@ -0,0 +1,47 @@
|
||||
= ERC-6909
|
||||
|
||||
ERC-6909 is a draft EIP that draws on ERC-1155 learnings since it was published in 2018. The main goals of ERC-6909 is to decrease gas costs and complexity--this is mainly accomplished by removing batching and callbacks.
|
||||
|
||||
TIP: To understand the inspiration for a multi token standard, see the xref:erc1155.adoc#multi-token-standard[multi token standard] section within the EIP-1155 docs.
|
||||
|
||||
== Changes from ERC-1155
|
||||
|
||||
There are three main changes from ERC-1155 which are as follows:
|
||||
|
||||
. The removal of batch operations.
|
||||
. The removal of transfer callbacks.
|
||||
. Granularization in approvals--approvals can be set globally (as operators) or as amounts per token (inspired by ERC20).
|
||||
|
||||
== Constructing an ERC-6909 Token Contract
|
||||
|
||||
We'll use ERC-6909 to track multiple items in a game, each having their own unique attributes. All item types will by minted to the deployer of the contract, which we can later transfer to players. We'll also use the xref:api:token/ERC6909.adoc#ERC6909Metadata[`ERC6909Metadata`] extension to add decimals to our fungible items (the vanilla ERC-6909 implementation does not have decimals).
|
||||
|
||||
For simplicity, we will mint all items in the constructor--however, minting functionality could be added to the contract to mint on demand to players.
|
||||
|
||||
TIP: For an overview of minting mechanisms, check out xref:erc20-supply.adoc[Creating ERC-20 Supply].
|
||||
|
||||
Here's what a contract for tokenized items might look like:
|
||||
|
||||
[source,solidity]
|
||||
----
|
||||
include::api:example$token/ERC6909/ERC6909GameItems.sol[]
|
||||
----
|
||||
|
||||
Note that there is no content URI functionality in the base implementation, but the xref:api:token/ERC6909.adoc#ERC6909ContentURI[`ERC6909ContentURI`] extension adds it. Additionally, the base implementation does not track total supplies, but the xref:api:token/ERC6909.adoc#ERC6909TokenSupply[`ERC6909TokenSupply`] extension tracks the total supply of each token id.
|
||||
|
||||
Once the contract is deployed, we will be able to query the deployer’s balance:
|
||||
[source,javascript]
|
||||
----
|
||||
> gameItems.balanceOf(deployerAddress, 3)
|
||||
1000000000
|
||||
----
|
||||
|
||||
We can transfer items to player accounts:
|
||||
[source,javascript]
|
||||
----
|
||||
> gameItems.transfer(playerAddress, 2, 1)
|
||||
> gameItems.balanceOf(playerAddress, 2)
|
||||
1
|
||||
> gameItems.balanceOf(deployerAddress, 2)
|
||||
0
|
||||
----
|
||||
@ -20,7 +20,7 @@ The ERC-20 extension to keep track of votes and vote delegation is one such case
|
||||
|
||||
=== Governor & GovernorStorage
|
||||
|
||||
An OpenZeppelin Governor contract is not interface-compatible with Compound's GovernorAlpha or Bravo. Even though events are fully compatible, proposal lifecycle functions (creation, execution, etc.) have different signatures that are meant to optimize storage use. Other functions from GovernorAlpha and Bravo are likewise not available. It’s possible to opt in some Bravo-like behavior by inheriting from the GovernorStorage module. This module provides proposal enumerability and alternate versions of the `queue`, `execute` and `cancel` function that only take the proposal id. This module reduces the calldata needed by some operations in exchange for an increased the storage footprint. This might be a good trade-off for some L2 chains. It also provides primitives for indexer-free frontends.
|
||||
An OpenZeppelin Governor contract is not interface-compatible with Compound's GovernorAlpha or Bravo. Even though events are fully compatible, proposal lifecycle functions (creation, execution, etc.) have different signatures that are meant to optimize storage use. Other functions from GovernorAlpha and Bravo are likewise not available. It’s possible to opt in some Bravo-like behavior by inheriting from the GovernorStorage module. This module provides proposal enumerability and alternate versions of the `queue`, `execute` and `cancel` function that only take the proposal id. This module reduces the calldata needed by some operations in exchange for an increased storage footprint. This might be a good trade-off for some L2 chains. It also provides primitives for indexer-free frontends.
|
||||
|
||||
Note that even with the use of this module, one important difference with Compound's GovernorBravo is the way that `proposalId`s are calculated. Governor uses the hash of the proposal parameters with the purpose of keeping its data off-chain by event indexing, while the original Bravo implementation uses sequential `proposalId`s.
|
||||
|
||||
@ -52,7 +52,7 @@ If your project already has a live token that does not include ERC20Votes and is
|
||||
include::api:example$governance/MyTokenWrapped.sol[]
|
||||
```
|
||||
|
||||
NOTE: The only other source of voting power available in OpenZeppelin Contracts currently is xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`]. ERC-721 tokens that don't provide this functionality can be wrapped into a voting tokens using a combination of xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`] and xref:api:token/ERC721Wrapper.adoc#ERC721Wrapper[`ERC721Wrapper`].
|
||||
NOTE: The only other source of voting power available in OpenZeppelin Contracts currently is xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`]. ERC-721 tokens that don't provide this functionality can be wrapped into a voting tokens using a combination of xref:api:token/ERC721.adoc#ERC721Votes[`ERC721Votes`] and xref:api:token/ERC721.adoc#ERC721Wrapper[`ERC721Wrapper`].
|
||||
|
||||
NOTE: The internal clock used by the token to store voting balances will dictate the operating mode of the Governor contract attached to it. By default, block numbers are used. Since v4.9, developers can override the xref:api:interfaces.adoc#IERC6372[IERC6372] clock to use timestamps instead of block numbers.
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ The guides in the sidebar will teach about different concepts, and how to use th
|
||||
|
||||
The xref:api:token/ERC20.adoc[full API] is also thoroughly documented, and serves as a great reference when developing your smart contract application. You can also ask for help or follow Contracts' development in the https://forum.openzeppelin.com[community forum].
|
||||
|
||||
Finally, you may want to take a look at the https://blog.openzeppelin.com/guides/[guides on our blog], which cover several common use cases and good practices. The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve.
|
||||
The following articles provide great background reading, though please note, some of the referenced tools have changed as the tooling in the ecosystem continues to rapidly evolve.
|
||||
|
||||
* https://blog.openzeppelin.com/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05[The Hitchhiker’s Guide to Smart Contracts in Ethereum] will help you get an overview of the various tools available for smart contract development, and help you set up your environment.
|
||||
* https://blog.openzeppelin.com/a-gentle-introduction-to-ethereum-programming-part-1-783cc7796094[A Gentle Introduction to Ethereum Programming, Part 1] provides very useful information on an introductory level, including many basic concepts from the Ethereum platform.
|
||||
|
||||
@ -12,7 +12,7 @@ At a high level, signatures are a set of cryptographic algorithms that allow for
|
||||
|
||||
==== Ethereum Signatures (secp256k1)
|
||||
|
||||
xref:api:utils.adoc#ECDSA[`ECDSA`] provides functions for recovering and managing Ethereum account ECDSA signatures. These are often generated via https://web3js.readthedocs.io/en/v1.7.3/web3-eth.html#sign[`web3.eth.sign`], and are a 65 byte array (of type `bytes` in Solidity) arranged the following way: `[[v (1)], [r (32)], [s (32)]]`.
|
||||
xref:api:utils.adoc#ECDSA[`ECDSA`] provides functions for recovering and managing Ethereum account ECDSA signatures. These are often generated via https://web3js.readthedocs.io/en/v1.7.3/web3-eth.html#sign[`web3.eth.sign`], and form a 65-byte array (of type `bytes` in Solidity) arranged the following way: `[[v (1)], [r (32)], [s (32)]]`.
|
||||
|
||||
The data signer can be recovered with xref:api:utils.adoc#ECDSA-recover-bytes32-bytes-[`ECDSA.recover`], and its address compared to verify the signature. Most wallets will hash the data to sign and add the prefix `\x19Ethereum Signed Message:\n`, so when attempting to recover the signer of an Ethereum signed message hash, you'll want to use xref:api:utils.adoc#MessageHashUtils-toEthSignedMessageHash-bytes32-[`toEthSignedMessageHash`].
|
||||
|
||||
@ -197,7 +197,7 @@ The `Enumerable*` structures are similar to mappings in that they store and remo
|
||||
|
||||
Building an on-chain Merkle Tree allows developers to keep track of the history of roots in a decentralized manner. For these cases, the xref:api:utils.adoc#MerkleTree[`MerkleTree`] includes a predefined structure with functions to manipulate the tree (e.g. pushing values or resetting the tree).
|
||||
|
||||
The Merkle Tree does not keep track of the roots purposely, so that developers can choose their tracking mechanism. Setting up and using a Merkle Tree in Solidity is as simple as follows:
|
||||
The Merkle Tree does not keep track of the roots intentionally, so that developers can choose their tracking mechanism. Setting up and using a Merkle Tree in Solidity is as simple as follows:
|
||||
|
||||
NOTE: Functions are exposed without access control for demonstration purposes
|
||||
|
||||
@ -243,7 +243,7 @@ function _hashFn(bytes32 a, bytes32 b) internal view returns(bytes32) {
|
||||
|
||||
=== Using a Heap
|
||||
|
||||
A https://en.wikipedia.org/wiki/Binary_heap[binary heap] is a data structure that always store the most important element at its peak and it can be used as a priority queue.
|
||||
A https://en.wikipedia.org/wiki/Binary_heap[binary heap] is a data structure that always stores the most important element at its peak and it can be used as a priority queue.
|
||||
|
||||
To define what is most important in a heap, these frequently take comparator functions that tell the binary heap whether a value has more relevance than another.
|
||||
|
||||
@ -358,7 +358,7 @@ This is especially useful for building URL-safe tokenURIs for both xref:api:toke
|
||||
|
||||
Here is an example to send JSON Metadata through a Base64 Data URI using an ERC-721:
|
||||
|
||||
[source, solidity]
|
||||
[source,solidity]
|
||||
----
|
||||
include::api:example$utilities/Base64NFT.sol[]
|
||||
----
|
||||
|
||||
Reference in New Issue
Block a user