Skip to content

Commit

Permalink
Update Sway Book and ownership example to use ownership library and s…
Browse files Browse the repository at this point in the history
…rc-5 standard (#4751)

## Description

The Sway Book's ownership example and documentation is outdated and does
not include the ownership library. It now links to the SRC-5 Ownership
standard, ownership library, and includes additional examples.

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: bitzoic <bitzoic.eth@gmail.com>
Co-authored-by: SwayStar123 <46050679+SwayStar123@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 18, 2023
1 parent 55fbbba commit 9195d63
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 41 deletions.
30 changes: 26 additions & 4 deletions docs/book/src/blockchain-development/access_control.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,38 @@ The `msg_sender` function works as follows:

## Contract Ownership

Many contracts require some form of ownership for access control. To accomplish this, it is recommended that a storage variable of type `Option<Identity>` is used to keep track of the owner. This allows setting and revoking ownership using the variants `Some(..)` and `None` respectively. This is better, safer, and more readable than using the `Identity` type directly where revoking ownership has to be done using some magic value such as `std::constants::ZERO_B256` or otherwise.
Many contracts require some form of ownership for access control. The [SRC-5 Ownership Standard](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_5) has been defined to provide a interoperable interface for ownership within contracts.

The following is an example of how to properly set ownership of a contract:
To accomplish this, use the [Ownerhsip Library](https://github.com/FuelLabs/sway-libs/tree/master/libs/ownership) to keep track of the owner. This allows setting and revoking ownership using the variants `Some(..)` and `None` respectively. This is better, safer, and more readable than using the `Identity` type directly where revoking ownership has to be done using some magic value such as `std::constants::ZERO_B256` or otherwise.

- The following is an example of how to properly lock a function such that only the owner may call a function:

```sway
{{#include ../../../../examples/ownership/src/main.sw:only_owner_example}}
```

Setting ownership can be done in one of two ways; During compile time or run time.

- The following is an example of how to properly set ownership of a contract during compile time:

```sway
{{#include ../../../../examples/ownership/src/main.sw:set_owner_example_storage}}
```

- The following is an example of how to properly set ownership of a contract during run time:

```sway
{{#include ../../../../examples/ownership/src/main.sw:set_owner_example}}
{{#include ../../../../examples/ownership/src/main.sw:set_owner_example_function}}
```

The following is an example of how to properly revoke ownership of a contract:
- The following is an example of how to properly revoke ownership of a contract:

```sway
{{#include ../../../../examples/ownership/src/main.sw:revoke_owner_example}}
```

- The following is an example of how to properly retrieve the state of ownership:

```sway
{{#include ../../../../examples/ownership/src/main.sw:get_owner_example}}
```
75 changes: 46 additions & 29 deletions examples/Forc.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ source = 'member'
[[package]]
name = 'array'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'asm_return_tuple_pointer'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'break_and_continue'
source = 'member'
dependencies = ['core']
dependencies = ['core path+from-root-087D5D776F294F03']

[[package]]
name = 'cei_analysis'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'configurable_constants'
Expand All @@ -30,10 +30,14 @@ source = 'member'
name = 'core'
source = 'path+from-root-087D5D776F294F03'

[[package]]
name = 'core'
source = 'path+from-root-9BFE6D5D0CBDF740'

[[package]]
name = 'counter'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'enums'
Expand All @@ -42,92 +46,105 @@ source = 'member'
[[package]]
name = 'fizzbuzz'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'hashing'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'identity'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'liquidity_pool'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'match_statements'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'methods_and_associated_functions'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'msg_sender'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'mut_ref_params'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'native_token'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'option'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'ownership'
source = 'git+https://github.com/FuelLabs/sway-libs?tag=v0.12.0#063f118a3104adb6a04207ca877993b5ad03a492'
dependencies = ['std git+https://github.com/fuellabs/sway?tag=v0.42.1#3b66f8e424bd21e3ba467783b10b36e808cfa6ee']

[[package]]
name = 'ownership'
source = 'member'
dependencies = ['std']
dependencies = [
'ownership git+https://github.com/FuelLabs/sway-libs?tag=v0.12.0#063f118a3104adb6a04207ca877993b5ad03a492',
'std path+from-root-087D5D776F294F03',
]

[[package]]
name = 'result'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'signatures'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'std'
source = 'git+https://github.com/fuellabs/sway?tag=v0.42.1#3b66f8e424bd21e3ba467783b10b36e808cfa6ee'
dependencies = ['core path+from-root-9BFE6D5D0CBDF740']

[[package]]
name = 'std'
source = 'path+from-root-087D5D776F294F03'
dependencies = ['core']
dependencies = ['core path+from-root-087D5D776F294F03']

[[package]]
name = 'storage_example'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'storage_map'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'storage_variables'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'storage_vec'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'structs'
Expand All @@ -136,7 +153,7 @@ source = 'member'
[[package]]
name = 'subcurrency'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'tuples'
Expand All @@ -145,30 +162,30 @@ source = 'member'
[[package]]
name = 'type_aliases'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'vec'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'wallet_abi'
source = 'member'
dependencies = ['std']
dependencies = ['std path+from-root-087D5D776F294F03']

[[package]]
name = 'wallet_contract_caller_script'
source = 'member'
dependencies = [
'std',
'std path+from-root-087D5D776F294F03',
'wallet_abi',
]

[[package]]
name = 'wallet_smart_contract'
source = 'member'
dependencies = [
'std',
'std path+from-root-087D5D776F294F03',
'wallet_abi',
]
1 change: 1 addition & 0 deletions examples/ownership/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ license = "Apache-2.0"
name = "ownership"

[dependencies]
ownership = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.12.0" }
std = { path = "../../sway-lib-std" }
32 changes: 24 additions & 8 deletions examples/ownership/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
contract;

use std::constants::ZERO_B256;
use ownership::{*, data_structures::State};

abi OwnershipExample {
#[storage(write)]
fn revoke_ownership();
#[storage(write)]
fn set_owner(identity: Identity);
#[storage(read)]
fn owner() -> Option<Identity>;
fn owner() -> State;
#[storage(read)]
fn only_owner();
}

// ANCHOR: set_owner_example_storage
storage {
owner: Option<Identity> = None,
owner: Ownership = Ownership::initialized(Identity::Address(Address::from(ZERO_B256))),
}
// ANCHOR_END: set_owner_example_storage

impl OwnershipExample for Contract {
// ANCHOR: revoke_owner_example
#[storage(write)]
fn revoke_ownership() {
storage.owner.write(None);
storage.owner.renounce_ownership();
}
// ANCHOR_END: revoke_owner_example
// ANCHOR: set_owner_example
// ANCHOR: set_owner_example_function
#[storage(write)]
fn set_owner(identity: Identity) {
storage.owner.write(Some(identity));
storage.owner.set_ownership(identity);
}
// ANCHOR_END: set_owner_example_function
// ANCHOR: get_owner_example
#[storage(read)]
fn owner() -> State {
storage.owner.owner()
}
// ANCHOR_END: set_owner_example
// ANCHOR_END: get_owner_example
// ANCHOR: only_owner_example
#[storage(read)]
fn owner() -> Option<Identity> {
storage.owner.read()
fn only_owner() {
storage.owner.only_owner();
// Do stuff here
}
// ANCHOR_END: only_owner_example
}

0 comments on commit 9195d63

Please sign in to comment.