6- Security and access control with OpenBrush

Prerequisites

Cargo contract installed: https://polkaverse.com/9768/technical-guide-install-cargo-contract-37738

At least on the following node is ready :

This tutorial uses Ubuntu 22.04, cargo 1.68, cargo contract 2.0 and swanky node

Create the project

You can use the command “cargo contract new” to create a new contract based on the template “flipper“.

cargo contract new security

Use OpenBrush

Add openbrush in your Cargo.toml and to the std features

openbrush = { git = "https://github.com/727-Ventures/openbrush-contracts", version = "3.1.1", default-features = false }

[features]
default = ["std"]
std = [
    "ink_metadata/std",
    "ink/std",
    "scale/std",
    "scale-info/std",
    "openbrush/std"
]

Ownable

OpenBrush provides only_owner rights for contract’s function

Step 1: Import default implementation

Add the feature ownable in your Cargo.toml

openbrush = { git = "https://github.com/727-Ventures/openbrush-contracts", version = "3.1.1", default-features = false, features = ["ownable"] }

After enabling the feature and importing the corresponding module, you need to embed the module data structure into your contract as a field and implement the openbrush::traits::Storage trait for that field. In most cases, the data structure of each module is named Data. If importing several modules, you can specify which data you want to use via namespaces like ownable::Data.

Each contract that wants to reuse implementation should implement the openbrush::traits::Storage with the corresponding data structure. The easiest way to implement that trait is via the derive macro by adding #[derive(Storage)] and marking the corresponding fields with the #[storage_field] attribute.

Now your contract has access to default implementation on the Rust level. It is on the Rust level so you can call methods only inside your contract (in the example, it is methods of Ownable, and ownable::Internal traits). If you want to make all methods of some trait public, you should explicitly implement the corresponding trait.

Note: 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). It also means you have to compile with the option nightly

Step 2: Define constructor

Define the constructor and initialize the owner with the contract initiator.

Step 3: Customize your contract

Customize it by adding ownable logic. We will add a only_owner function to SecuryContract implemenation and add the only_owner modifier, which will verify that the caller of the function is the owner.

Build the project

In the directory “security“, use the command “cargo +nightly contract build” to compile the project.

cargo +nightly contract build

Deploy the contract

You can deploy your contract in a local node or a swanky node or a testnet.

Here we will start a swanky node and use Contracts UI to interact with the contract.

Here the result when the contract’s owner calls the method onlyOwner

Here the result when a non contract’s owner calls the method onlyOwner. The error CallerIsNotOwner is returned by the method.

And you can also use the transferOwnership function to transfer the ownership of this contract or play with the following functions

Access Control

OpenBrush provides only_role rights for contract’s function

Step 1: Import default implementation

Add the feature access_control in your Cargo.toml

openbrush = { git = "https://github.com/727-Ventures/openbrush-contracts", version = "3.1.1", default-features = false, features = ["ownable", "access_control"] }

After enabling the feature and importing the corresponding module, you need to embed the module data structure into your contract as a field.

Now your contract has access to default implementation on the Rust level. It is on the Rust level so you can call methods only inside your contract. If you want to make all methods of some trait public, you should explicitly implement the corresponding trait.

Step 2: Define constructor

You can initialize the admin role for the owner with the contract initiator and you can also grant default roles for for the owner.

Step 3: Customize your contract

Customize it by adding access control logic. We will add a only_role_1 and only_role_2 functions to SecuryContract implemenation. We also add getter for displaying the value behind each role.

Build the project

In the directory “security“, use the command “cargo +nightly contract build” to compile the project.

cargo +nightly contract build

Deploy the contract

You can deploy your contract in a local node or a swanky node or a testnet.

Here we will start a swanky node and use Contracts UI to interact with the contract.

Here the result when the user is granted to call the method.

Here the result when the user is not granted to call the method. The error MissingRole is returned by the method.

And you can use the grantRole/revokeRole functions to grant/revoke a role to the address. You can also use the following functions:

Conclusion

Manage the access control is very important when deploying a smart contract in the blockchain. OpenBrush allows an easy way to provide rights for usage of specific smart contract functions.

Git repository

https://github.com/GuiGou12358/astar-tutorials/tree/main/tuto6

Source

https://learn.brushfam.io/docs/OpenBrush/smart-contracts/ownable

https://learn.brushfam.io/docs/OpenBrush/smart-contracts/access-control/

0
GuiGouPost author

Crypto-enthusiast, Defi & NFT believer, Dotsam Fam Astar Tech Amb & Phala Amb Web2 builder gradually migrating to Web3

Tutorials to write Smart Contracts in Rust and Ink!

0 comments

Tutorials to write Smart Contracts in Rust and Ink!