utilities.adoc 5.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. = Utilities
  2. OpenZeppelin provides a ton of useful utilities that you can use in your project. Here are some of the more popular ones:
  3. [[cryptography]]
  4. == Cryptography
  5. * xref:api:cryptography.adoc#ECDSA[`ECDSA`] — provides functions for recovering and managing Ethereum account ECDSA signatures:
  6. * to use it, declare: `using ECDSA for bytes32;`
  7. * signatures are tightly packed, 65 byte `bytes` that look like `{v (1)} {r (32)} {s (32)}`
  8. ** this is the default from `web3.eth.sign` so you probably don't need to worry about this format
  9. * recover the signer using xref:api:cryptography.adoc#ECDSA-recover-bytes32-bytes-[`myDataHash.recover(signature)`]
  10. * if you are using `eth_personalSign`, the signer will hash your data and then add the prefix `\x19Ethereum Signed Message:\n`, so if you're attempting to recover the signer of an Ethereum signed message hash, you'll want to use xref:api:cryptography.adoc#ECDSA-toEthSignedMessageHash-bytes32-[`toEthSignedMessageHash`]
  11. Use these functions in combination to verify that a user has signed some information on-chain:
  12. [source,solidity]
  13. ----
  14. keccack256(
  15. abi.encodePacked(
  16. someData,
  17. moreData
  18. )
  19. )
  20. .toEthSignedMessageHash()
  21. .recover(signature)
  22. ----
  23. * xref:api:cryptography.adoc#MerkleProof[`MerkleProof`] — provides xref:api:cryptography.adoc#MerkleProof-verify-bytes32---bytes32-bytes32-[`verify`] for verifying merkle proofs.
  24. [[introspection]]
  25. == Introspection
  26. In Solidity, it's frequently helpful to know whether or not a contract supports an interface you'd like to use. ERC165 is a standard that helps do runtime interface detection. OpenZeppelin provides some helpers, both for implementing ERC165 in your contracts and querying other contracts:
  27. * xref:api:introspection.adoc#IERC165[`IERC165`] — this is the ERC165 interface that defines xref:api:introspection.adoc#IERC165-supportsInterface-bytes4-[`supportsInterface`]. When implementing ERC165, you'll conform to this interface.
  28. * xref:api:introspection.adoc#ERC165[`ERC165`] — inherit this contract if you'd like to support interface detection using a lookup table in contract storage. You can register interfaces using xref:api:introspection.adoc#ERC165-_registerInterface-bytes4-[`_registerInterface(bytes4)`]: check out example usage as part of the ERC721 implementation.
  29. * xref:api:introspection.adoc#ERC165Checker[`ERC165Checker`] — ERC165Checker simplifies the process of checking whether or not a contract supports an interface you care about.
  30. * include with `using ERC165Checker for address;`
  31. * xref:api:introspection.adoc#ERC165Checker-_supportsInterface-address-bytes4-[`myAddress._supportsInterface(bytes4)`]
  32. * xref:api:introspection.adoc#ERC165Checker-_supportsAllInterfaces-address-bytes4---[`myAddress._supportsAllInterfaces(bytes4[])`]
  33. [source,solidity]
  34. ----
  35. contract MyContract {
  36. using ERC165Checker for address;
  37. bytes4 private InterfaceId_ERC721 = 0x80ac58cd;
  38. /**
  39. * @dev transfer an ERC721 token from this contract to someone else
  40. */
  41. function transferERC721(
  42. address token,
  43. address to,
  44. uint256 tokenId
  45. )
  46. public
  47. {
  48. require(token.supportsInterface(InterfaceId_ERC721), "IS_NOT_721_TOKEN");
  49. IERC721(token).transferFrom(address(this), to, tokenId);
  50. }
  51. }
  52. ----
  53. [[math]]
  54. == Math
  55. The most popular math related library OpenZeppelin provides is xref:api:math.adoc#SafeMath[`SafeMath`], which provides mathematical functions that protect your contract from overflows and underflows.
  56. Include the contract with `using SafeMath for uint256;` and then call the functions:
  57. * `myNumber.add(otherNumber)`
  58. * `myNumber.sub(otherNumber)`
  59. * `myNumber.div(otherNumber)`
  60. * `myNumber.mul(otherNumber)`
  61. * `myNumber.mod(otherNumber)`
  62. Easy!
  63. [[payment]]
  64. == Payment
  65. Want to split some payments between multiple people? Maybe you have an app that sends 30% of art purchases to the original creator and 70% of the profits to the current owner; you can build that with xref:api:payment.adoc#PaymentSplitter[`PaymentSplitter`]!
  66. In solidity, there are some security concerns with blindly sending money to accounts, since it allows them to execute arbitrary code. You can read up on these security concerns in the https://consensys.github.io/smart-contract-best-practices/[Ethereum Smart Contract Best Practices] website. One of the ways to fix reentrancy and stalling problems is, instead of immediately sending Ether to accounts that need it, you can use xref:api:payment.adoc#PullPayment[`PullPayment`], which offers an xref:api:payment.adoc#PullPayment-_asyncTransfer-address-uint256-[`_asyncTransfer`] function for sending money to something and requesting that they xref:api:payment.adoc#PullPayment-withdrawPayments-address-payable-[`withdrawPayments()`] it later.
  67. If you want to Escrow some funds, check out xref:api:payment.adoc#Escrow[`Escrow`] and xref:api:payment.adoc#ConditionalEscrow[`ConditionalEscrow`] for governing the release of some escrowed Ether.
  68. [[misc]]
  69. === Misc
  70. Want to check if an address is a contract? Use xref:api:utils.adoc#Address[`Address`] and xref:api:utils.adoc#Address-isContract-address-[`Address.isContract()`].
  71. Want to keep track of some numbers that increment by 1 every time you want another one? Check out xref:api:drafts.adoc#Counter[`Counter`]. This is especially useful for creating incremental ERC721 `tokenId`s like we did in the last section.