*`ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
*`ERC721`: added a constructor for `name` and `symbol`. ([#2160](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2160))
*`ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
*`ERC20Detailed`: this contract was removed and its functionality merged into `ERC20`. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
*`ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
*`ERC20`: added a constructor for `name` and `symbol`. `decimals` now defaults to 18. ([#2161](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2161))
*`Strings`: renamed `fromUint256` to `toString` ([#2188](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2188))
## 2.5.0 (2020-02-04)
## 2.5.0 (2020-02-04)
...
@@ -127,7 +128,7 @@ Refer to the table below to adjust your inheritance list.
...
@@ -127,7 +128,7 @@ Refer to the table below to adjust your inheritance list.
### Improvements
### Improvements
* Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
* Upgraded the minimum compiler version to v0.5.2: this removes many Solidity warnings that were false positives. ([#1606](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1606))
*`ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622))
*`ECDSA`: `recover` no longer accepts malleable signatures (those using upper-range values for `s`, or 0/1 for `v`). ([#1622](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1622))
*`ERC721`'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
*``ERC721``'s transfers are now more gas efficient due to removal of unnecessary `SafeMath` calls. ([#1610](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1610))
This document describes our release process, and contains the steps to be followed by an OpenZeppelin maintainer at the several stages of a release.
> Visit the documentation for [details about release schedule].
We release a new version of OpenZeppelin monthly. Release cycles are tracked in the [issue milestones](https://github.com/OpenZeppelin/openzeppelin-contracts/milestones).
Start on an up-to-date `master` branch.
Each release has at least one release candidate published first, intended for community review and any critical fixes that may come out of it. At the moment we leave 1 week between the first release candidate and the final release.
Create the release branch with `npm run release start minor`.
Before starting make sure to verify the following items.
Publish a release candidate with `npm run release rc`.
* Your local `master` branch is in sync with your `upstream` remote (it may have another name depending on your setup).
* Your repo is clean, particularly with no untracked files in the contracts and tests directories. Verify with `git clean -n`.
Publish the final release with `npm run release final`.
## Creating the release branch
Follow the general [OpenZeppelin release checklist].
We'll refer to a release `vX.Y.Z`.
[details about release schedule]:https://docs.openzeppelin.com/contracts/releases-stability
Once in the release branch, change the version string in `package.json`, `package-lock.json` and `ethpm.json` to `X.Y.Z-rc.R`. (This will be `X.Y.Z-rc.1` for the first release candidate.) Commit these changes and tag the commit as `vX.Y.Z-rc.R`.
```
git add package.json package-lock.json ethpm.json
git commit -m "Release candidate vX.Y.Z-rc.R"
git tag -a vX.Y.Z-rc.R
git push upstream release-vX.Y.Z
git push upstream vX.Y.Z-rc.R
```
Draft the release notes in our [GitHub releases](https://github.com/OpenZeppelin/openzeppelin-contracts/releases). Make sure to mark it as a pre-release! Try to be consistent with our previous release notes in the title and format of the text. Release candidates don't need a detailed changelog, but make sure to include a link to GitHub's compare page.
Once the CI run for the new tag is green, publish on npm under the `next` tag. You should see the contracts compile automatically.
```
npm publish --tag next
```
Publish the release notes on GitHub and the forum, and ask our community manager to announce the release candidate on at least Twitter.
## Creating the final release
Make sure to have the latest changes from `upstream` in your local release branch.
```
git checkout release-vX.Y.Z
git pull upstream
```
Before starting the release process, make one final commit to CHANGELOG.md, including the date of the release.
Change the version string in `package.json`, `package-lock.json` and `ethpm.json` removing the "-rc.R" suffix. Commit these changes and tag the commit as `vX.Y.Z`.
```
git add package.json package-lock.json ethpm.json
git commit -m "Release vX.Y.Z"
git tag -a vX.Y.Z
git push upstream release-vX.Y.Z
git push upstream vX.Y.Z
```
Draft the release notes in GitHub releases. Try to be consistent with our previous release notes in the title and format of the text. Make sure to include a detailed changelog.
Once the CI run for the new tag is green, publish on npm. You should see the contracts compile automatically.
```
npm publish
```
Publish the release notes on GitHub and ask our community manager to announce the release!
Delete the `next` tag in the npm package as there is no longer a release candidate.
```
npm dist-tag rm --otp $2FA_CODE @openzeppelin/contracts next
These contracts integrate different Ethereum standards (ERCs) with custom extensions and modules, showcasing common configurations that are ready to deploy **without having to write any Solidity code**.
These contracts integrate different Ethereum standards (ERCs) with custom extensions and modules, showcasing common configurations that are ready to deploy **without having to write any Solidity code**.
...
@@ -8,6 +8,6 @@ TIP: Intermediate and advanced users can use these as starting points when writi
...
@@ -8,6 +8,6 @@ TIP: Intermediate and advanced users can use these as starting points when writi
Miscellaneous contracts containing utility functions, often related to working with different data types.
Miscellaneous contracts and libraries containing utility functions you can use to improve security, work with new data types, or safely use low-level primitives.
Security tools include:
* {Pausable}: provides a simple way to halt activity in your contracts (often in reponse to an external threat).
* {ReentrancyGuard}: protects you from https://blog.openzeppelin.com/reentrancy-after-istanbul/[reentrant calls].
The {Address}, {Arrays} and {Strings} libraries provide more operations related to these native data types, while {SafeCast} adds ways to safely convert between the different signed and unsigned numeric types.
For new data types:
* {Counters}: a simple way to get a counter that can only be incremented or decremented. Very useful for ID generation, counting contract activity, among others.
* {EnumerableMap}: like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] type, but with key-value _enumeration_: this will let you know how many entries a mapping has, and iterate over them (which is not possible with `mapping`).
* {EnumerableSet}: like {EnumerableMap}, but for https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets]. Can be used to store privileged accounts, issued IDs, etc.
[NOTE]
====
Because Solidity does not support generic types, {EnumerableMap} and {EnumerableSet} are specialized to a limited number of key-value types.
As of v3.0, {EnumerableMap} supports `uint256 -> address` (`UintToAddressMap`), and {EnumerableSet} supports `address` and `uint256` (`AddressSet` and `UintSet`).
====
Finally, {Create2} contains all necessary utilities to safely use the https://blog.openzeppelin.com/getting-the-most-out-of-create2/[`CREATE2` EVM opcode], without having to deal with low-level assembly.
In this case, we'll be extending from the xref:api:token/ERC777.adoc#ERC777[`ERC777`] contract, which provides an implementation with compatibility support for ERC20. The API is quite similar to that of xref:api:token/ERC777.adoc#ERC777[`ERC777`], and we'll once again make use of xref:api:token/ERC777.adoc#ERC777-_mint-address-address-uint256-bytes-bytes-[`_mint`] to assign the `initialSupply` to the deployer account. Unlike xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[ERC20's `_mint`], this one includes some extra parameters, but you can safely ignore those for now.
In this case, we'll be extending from the xref:api:token/ERC777.adoc#ERC777[`ERC777`] contract, which provides an implementation with compatibility support for ERC20. The API is quite similar to that of xref:api:token/ERC777.adoc#ERC777[`ERC777`], and we'll once again make use of xref:api:token/ERC777.adoc#ERC777-_mint-address-address-uint256-bytes-bytes-[`_mint`] to assign the `initialSupply` to the deployer account. Unlike xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[ERC20's `_mint`], this one includes some extra parameters, but you can safely ignore those for now.
You'll notice both xref:api:token/ERC777.adoc#IERC777-name--[`name`] and xref:api:token/ERC777.adoc#IERC777-symbol--[`symbol`] are assigned, but not xref:api:token/ERC777.adoc#ERC777-decimals--[`decimals`]. The ERC777 specification makes it mandatory to include support for these functions (unlike ERC20, where it is optional and we had to include xref:api:token/ERC20.adoc#ERC20Detailed[`ERC20Detailed`]), but also mandates that `decimals` always returns a fixed value of `18`, so there's no need to set it ourselves. For a review of `decimals`'s role and importance, refer back to our xref:erc20.adoc#a-note-on-decimals[ERC20 guide].
You'll notice both xref:api:token/ERC777.adoc#IERC777-name--[`name`] and xref:api:token/ERC777.adoc#IERC777-symbol--[`symbol`] are assigned, but not xref:api:token/ERC777.adoc#ERC777-decimals--[`decimals`]. The ERC777 specification makes it mandatory to include support for these functions (unlike ERC20, where it is optional and we had to include xref:api:token/ERC20.adoc#ERC20Detailed[`ERC20Detailed`]), but also mandates that `decimals` always returns a fixed value of `18`, so there's no need to set it ourselves. For a review of ``decimals``'s role and importance, refer back to our xref:erc20.adoc#a-note-on-decimals[ERC20 guide].
Finally, we'll need to set the xref:api:token/ERC777.adoc#IERC777-defaultOperators--[`defaultOperators`]: special accounts (usually other smart contracts) that will be able to transfer tokens on behalf of their holders. If you're not planning on using operators in your token, you can simply pass an empty array. _Stay tuned for an upcoming in-depth guide on ERC777 operators!_
Finally, we'll need to set the xref:api:token/ERC777.adoc#IERC777-defaultOperators--[`defaultOperators`]: special accounts (usually other smart contracts) that will be able to transfer tokens on behalf of their holders. If you're not planning on using operators in your token, you can simply pass an empty array. _Stay tuned for an upcoming in-depth guide on ERC777 operators!_
...
@@ -49,7 +49,7 @@ That's it for a basic token contract! We can now deploy it, and use the same xre
...
@@ -49,7 +49,7 @@ That's it for a basic token contract! We can now deploy it, and use the same xre
1000
1000
----
----
To move tokens from one account to another, we can use both xref:api:token/ERC777.adoc#ERC777-transfer-address-uint256-[`ERC20`'s `transfer`] method, or the new xref:api:token/ERC777.adoc#ERC777-send-address-uint256-bytes-[`ERC777`'s `send`], which fulfills a very similar role, but adds an optional `data` field:
To move tokens from one account to another, we can use both xref:api:token/ERC777.adoc#ERC777-transfer-address-uint256-[``ERC20``'s `transfer`] method, or the new xref:api:token/ERC777.adoc#ERC777-send-address-uint256-bytes-[``ERC777``'s `send`], which fulfills a very similar role, but adds an optional `data` field:
Most of the OpenZeppelin Contracts are expected to be used via https://solidity.readthedocs.io/en/latest/contracts.html#inheritance[inheritance]: you will _inherit_ from them when writing your own contracts.
This is the commonly found `is` syntax, like in `contract MyToken is ERC20`.
[NOTE]
====
Unlike ``contract``s, Solidity ``library``s are not inherited from and instead rely on the https://solidity.readthedocs.io/en/latest/contracts.html#using-for[`using for`] syntax.
OpenZeppelin Contracts has some ``library``s: most are in the xref:api:utils.adoc[Utils] directory.
====
== Overriding
Inheritance is often used to add the parent contract's functionality to your own contract, but that's not all it can do. You can also _change_ how some parts of the parent behave using _overrides_.
For example, imagine you want to change xref:api:access.adoc#AccessControl[`AccessControl`] so that xref:api:access.adoc#AccessControl-revokeRole-bytes32-address-[`revokeRole`] can no longer be called. This can be achieved using overrides:
The old `revokeRole` is then replaced by our override, and any calls to it will immediately revert. We cannot _remove_ the function from the contract, but reverting on all calls is good enough.
=== Calling `super`
Sometimes you want to _extend_ a parent's behavior, instead of outright changing it to something else. This is where `super` comes in.
The `super` keyword will let you call functions defined in a parent contract, even if they are overridden. This mechanism can be used to add additional checks to a function, emit events, or otherwise add functionality as you see fit.
TIP: For more information on how overrides work, head over to the https://solidity.readthedocs.io/en/latest/contracts.html#index-17[official Solidity documentation].
Here is a modified version of xref:api:access.adoc#AccessControl[`AccessControl`] where xref:api:access.adoc#AccessControl-revokeRole-bytes32-address-[`revokeRole`] cannot be used to revoke the `DEFAULT_ADMIN_ROLE`:
The `super.revokeRole` statement at the end will invoke ``AccessControl``'s original version of `revokeRole`, the same code that would've run if there were no overrides in place.
NOTE: As of v3.0.0, `view` functions are not `virtual` in OpenZeppelin, and therefore cannot be overriden. We're considering https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2154[lifting this restriction] in an upcoming release. Let us know if this is something you care about!
[[using-hooks]]
== Using Hooks
Sometimes, in order to extend a parent contract you will need to override multiple related functions, which leads to code duplication and increased likelihood of bugs.
For example, consider implementing safe xref:api:token/ERC20.adoc#ERC20[`ERC20`] transfers in the style of xref:api:token/ERC721.adoc#IERC721Receiver[`IERC721Receiver`]. You may think overriding xref:api:token/ERC20.adoc#ERC20-transfer-address-uint256-[`transfer`] and xref:api:token/ERC20.adoc#ERC20-transferFrom-address-address-uint256-[`transferFrom`] would be enough, but what about xref:api:token/ERC20.adoc#ERC20-_transfer-address-address-uint256-[`_transfer`] and xref:api:token/ERC20.adoc#ERC20-_mint-address-uint256-[`_mint`]? To prevent you from having to deal with these details, we introduced **hooks**.
Hooks are simply functions that are called before or after some action takes place. They provide a centralized point to _hook into_ and extend the original behavior.
Here's how you would implement the `IERC721Receiver` pattern in `ERC20`, using the xref:api:token/ERC20.adoc#ERC20-_beforeTokenTransfer-address-address-uint256-[`_beforeTokenTransfer`] hook:
function _validRecipient(address to) private view returns (bool) {
...
}
```
Using hooks this way leads to cleaner and safer code, without having to rely on a deep understanding of the parent's internals.
[NOTE]
====
Hooks are a new feature of OpenZeppelin Contracts v3.0.0, and we're eager to learn how you plan to use them!
So far, the only available hook is `_beforeTransferHook`, in all of xref:api:token/ERC20.adoc#ERC20-_beforeTokenTransfer-address-address-uint256-[`ERC20`], xref:api:token/ERC721.adoc#ERC721-_beforeTokenTransfer-address-address-uint256-[ERC721] and xref:api:token/ERC777.adoc#ERC777-_beforeTokenTransfer-address-address-address-uint256-[ERC777]. If you have ideas for new hooks, let us know!
====
=== Rules of Hooks
There's a few guidelines you should follow when writing code that uses hooks in order to prevent issues. They are very simple, but do make sure you follow them:
1. Whenever you override a parent's hook, re-apply the `virtual` attribute to the hook. That will allow child contracts to add more functionality to the hook.
2. **Always** call the parent's hook in your override using `super`. This will make sure all hooks in the inheritance tree are called: contracts like xref:api:token/ERC20.adoc#ERC20Pausable[`ERC20Pausable`] rely on this behavior.
```solidity
contract MyToken is ERC20 {
function _beforeTokenTransfer(address from, address to, uint256 amount)
internal virtual override // Add virtual here!
{
super._beforeTokenTransfer(from, to, amount); // Call parent hook
OpenZeppelin Contracts has a *5 week release cycle*. This means that every five weeks a new release is published.
OpenZeppelin Contracts aims for a new minor release every 1 or 2 months.
At the beginning of the release cycle we decide which issues we want to prioritize, and assign them to https://github.com/OpenZeppelin/openzeppelin-contracts/milestones[a milestone on GitHub]. During the next five weeks, they are worked on and fixed.
At the beginning of the release cycle we decide which issues we want to prioritize, and assign them to https://github.com/OpenZeppelin/openzeppelin-contracts/milestones[a milestone on GitHub]. During the next five weeks, they are worked on and fixed.
...
@@ -21,7 +21,7 @@ Once the milestone is complete, we publish a feature-frozen release candidate. T
...
@@ -21,7 +21,7 @@ Once the milestone is complete, we publish a feature-frozen release candidate. T
[[major-releases]]
[[major-releases]]
=== Major Releases
=== Major Releases
Every several months a new major release may come out. These are not scheduled, but will be based on the need to release breaking changes such as a redesign of a core feature of the library (e.g. https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1146[roles] in 2.0). Since we value stability, we aim for these to happen infrequently (expect no less than six months between majors). However, we may be forced to release one when there are big changes to the Solidity language.
After several months or a year a new major release may come out. These are not scheduled, but will be based on the need to release breaking changes such as a redesign of a core feature of the library (e.g. https://github.com/OpenZeppelin/openzeppelin-contracts/pulls/2112[access control] in 3.0). Since we value stability, we aim for these to happen infrequently (expect no less than six months between majors). However, we may be forced to release one when there are big changes to the Solidity language.