Skip to content

Commit

Permalink
Merge pull request #108 from Brushfam/feature/update-reentrancy-example
Browse files Browse the repository at this point in the history
  • Loading branch information
Artemka374 authored Jul 20, 2023
2 parents 6f36a95 + 25adb8e commit c30074d
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 24 deletions.
20 changes: 10 additions & 10 deletions docs/docs/smart-contracts/example/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ title: Data and derive macro

Rust doesn't have inheritance like OOP languages.
If you want to "inherit" some fields, you can use structural composition.
If you want to "inherit" some implementation, you can use traits.
If you want to "inherit" some implementation, you can use traits.
Traits can have a [default implementation](https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations) or a [generic implementation](https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods).
The traits in Rust can't contain fields, it is pure interfaces.

Based on that information we propose you the following concept of smart contract
Based on that information we propose you the following concept of smart contract
development:

### Storage trait
Expand All @@ -31,13 +31,13 @@ pub trait PointStorage {
Or you can use `openbrush::traits::Storage` trait from OpenBrush.

`Storage` is a generic trait, so you can use it to work with different storage.
For example, if in your default implementation you need to have `psp22::extensions::metadata::Data` and `psp22::Data`,
For example, if in your default implementation you need to have `psp22::extensions::metadata::Data` and `psp22::Data`,
you can add bounds `T: Storage<metadata::Data> + Storage<psp22::Data>`.
It allows you to work with two independent storage.

### Data of the trait

That trait returns some data with fields that can be used in the implementation.
That trait returns some data with fields that can be used in the implementation.
The data is a simple struct with fields. Later that struct can be embedded into the contract struct.
```rust
pub struct PointData {
Expand Down Expand Up @@ -73,7 +73,7 @@ pub struct PointData {

### Default implementation

Define the default or generic implementation for your main trait with the restriction that `Self`
Define the default or generic implementation for your main trait with the restriction that `Self`
should also implement storage trait.

A default implementation with impl trait:
Expand All @@ -82,11 +82,11 @@ pub trait PointImpl: PointStorage {
fn x(&self) -> u32 {
PointStorage::get(self).x
}

fn y(&self) -> u32 {
PointStorage::get(self).y
}

fn name(&self) -> String {
"AlphaPoint".to_string()
}
Expand All @@ -110,11 +110,11 @@ pub trait Point: openbrush::traits::Storage<PointData> {
fn x(&self) -> u32 {
self.data().x
}

fn y(&self) -> u32 {
self.data().y
}

fn name(&self) -> String {
"AlphaPoint".to_string()
}
Expand All @@ -134,7 +134,7 @@ pub trait Point {

### "Inheritance" of the implementation

When someone wants to "inherit" implementation and fields, he can embed the data structure,
When someone wants to "inherit" implementation and fields, he can embed the data structure,
implement the storage trait, and define an impl section of the main trait:
```rust
struct PointContract {
Expand Down
1 change: 0 additions & 1 deletion examples/payment_splitter/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#[openbrush::implementation(PaymentSplitter)]
#[openbrush::contract]
pub mod my_payment_splitter {
use ink::prelude::vec::Vec;
use openbrush::traits::Storage;

#[ink(storage)]
Expand Down
18 changes: 10 additions & 8 deletions examples/reentrancy_guard/contracts/flip_on_me/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

pub use openbrush::examples::contracts::reentrancy_guard::flip_on_me::*;

#[openbrush::contract]
pub mod flip_on_me {
use flipper::traits::flipper::*;
use flipper::traits::flip_on_me::*;
use ink::codegen::Env;
use ink::env::CallFlags;
use openbrush::traits::DefaultEnv;

#[ink(storage)]
#[derive(Default)]
Expand All @@ -17,16 +21,14 @@ pub mod flip_on_me {
}

impl FlipOnMe for FlipOnMeContract {
#[ink(message)]
fn flip_on_me(&mut self) -> Result<(), ReentrancyGuardError> {
let caller = self.env().caller();
self.flip_on_target(caller)
}

#[ink(message)]
fn flip_on_target(&mut self, callee: AccountId) -> Result<(), ReentrancyGuardError> {
// This method does a cross-contract call to caller contract and calls the `flip` method.
flipper::traits::flipper::FlipperRef::flip(&callee)
FlipperRef::flip_builder(&callee)
.call_flags(CallFlags::default().set_allow_reentry(true))
.invoke()
.unwrap();
Ok(())
}
}
}
12 changes: 11 additions & 1 deletion examples/reentrancy_guard/contracts/flipper/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

pub use openbrush::examples::contracts::reentrancy_guard::my_flipper_guard::*;

#[openbrush::contract]
pub mod my_flipper_guard {
use flipper::traits::flipper::*;
use flipper::traits::flip_on_me::*;
use openbrush::{
modifiers,
traits::Storage,
};
use ink::env::CallFlags;
use openbrush::traits::DefaultEnv;


#[ink(storage)]
#[derive(Default, Storage)]
Expand Down Expand Up @@ -43,7 +49,11 @@ pub mod my_flipper_guard {
// Callee contract during execution of `flip_on_me` will call `flip` of this contract.
// `call_flip_on_me` and `flip` are marked with `non_reentrant` modifier. It means,
// that call of `flip` after `call_flip_on_me` must fail.
flipper::traits::flip_on_me::FlipOnMeRef::flip_on_me(&callee)
FlipOnMeRef::flip_on_target_builder(&callee, Self::env().account_id())
.call_flags(CallFlags::default().set_allow_reentry(true))
.invoke()
.unwrap();
Ok(())
}
}
}
3 changes: 0 additions & 3 deletions examples/reentrancy_guard/traits/flip_on_me.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pub type FlipOnMeRef = dyn FlipOnMe;

#[openbrush::trait_definition]
pub trait FlipOnMe {
#[ink(message)]
fn flip_on_me(&mut self) -> Result<(), ReentrancyGuardError>;

#[ink(message)]
fn flip_on_target(&mut self, callee: AccountId) -> Result<(), ReentrancyGuardError>;
}
1 change: 0 additions & 1 deletion examples/timelock_controller/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#[openbrush::implementation(AccessControl, TimelockController)]
#[openbrush::contract]
pub mod my_timelock_controller {
use ink::prelude::vec::Vec;
use openbrush::traits::Storage;

#[ink(storage)]
Expand Down

0 comments on commit c30074d

Please sign in to comment.