Skip to main content

Overview

This doc contains description of how the OpenBrush library can be imported and used.

The OpenBrush is using ink! stable release v3.0.0 branch at the moment. So you should use the same version of the ink! across your project.

The default toml of your project with OpenBrush:

[dependencies]
# Import of all ink! crates
ink_primitives = { version = "~3.3.0", default-features = false }
ink_metadata = { version = "~3.3.0", default-features = false, features = ["derive"], optional = true }
ink_env = { version = "~3.3.0", default-features = false }
ink_storage = { version = "~3.3.0", default-features = false }
ink_lang = { version = "~3.3.0", default-features = false }
ink_prelude = { version = "~3.3.0", default-features = false }
ink_engine = { version = "~3.3.0", default-features = false, optional = true }

scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"], optional = true }

# Brush dependency
openbrush = { version = "~2.1.0", default-features = false }

[features]
default = ["std"]
std = [
"ink_primitives/std",
"ink_metadata",
"ink_metadata/std",
"ink_env/std",
"ink_storage/std",
"ink_lang/std",
"scale/std",
"scale-info",
"scale-info/std",

# Brush dependency
"openbrush/std",
]
ink-as-dependency = []

To avoid unexpected compilation errors better to always import all ink! crates.

By default, the openbrush crate provides macros for simplification of the development and traits of contracts(you can implement them by yourself, and you can use them for a cross-contract calls).

The OpenBrush also provides the default implementation of traits that can be enabled via crate features. A list of all available features you can find here. The default implementation of traits requires the usage of the unstable feature min-specialization. You can enable it by adding #![feature(min_specialization)] at the top of your root module(for more information check rust official documentation).

Note: ink! requires put #![cfg_attr(not(feature = "std"), no_std)] at the top of root crate.

Note: Some default implementations for traits provide additional methods that can be overridden. These methods are defined in a separate internal trait. It has the name of the original trait + suffix Internal. If you want to override them you need to do that in the impl section of the internal trait.

Also, that doc contains links to the examples of how to reuse and customize the default implementation of traits.

  • PSP22 is an example of how you can reuse the implementation of psp22. You also can find examples of how to reuse extensions.
    • PSP22Metadata: metadata for PSP22.
    • PSP22Mintable: creation of new tokens.
    • PSP22Burnable: destruction of own tokens.
    • PSP22Wrapper: wrapper for PSP22 token (useful for governance tokens etc.).
    • PSP22FlashMint: extension which allows performing flashloans of the token by minting and burning the token.
    • PSP22Pausable: example of using pausable extension in the PSP22 contract.
    • PSP22Capped: extension which adds a cap for total supply of PSP22 tokens.
    • PSP22TokenTimelock: Utility which allows token holders to lock their tokens for a specified amount of time.
  • PSP34 is an example of how you can reuse the implementation of psp34. You also can find examples of how to reuse extensions.
  • PSP35 is an example of how you can reuse the implementation of psp35. You also can find examples of how to reuse extensions.
  • Access Control shows how you can use the implementation of access-control and psp34 together to provide rights to mint and burn NFT tokens.
  • Ownable shows how you can use the implementation of ownable and psp35 together to provide rights to mint and burn tokens.
  • ReentrancyGuard shows how you can use the implementation of non_reentrant modifier to prevent reentrancy during certain functions.
  • Pausable shows how you can use the implementation of pausable contract and modifiers.
  • TimelockController shows how you can use the implementation of timelock-controller to execute a transaction with some delay via governance.
  • PaymentSplitter shows how you can use the implementation of payment-splitter to split received native tokens between participants of the contract.
  • Diamond shows how you can use the implementation of diamond pattern to split your contract into small parts and support upgradability.
  • Proxy shows how you can use the implementation of proxy pattern to support upgradability of your contract.