diff --git a/docs/book/src/blockchain-development/access_control.md b/docs/book/src/blockchain-development/access_control.md index 10afdd954d8..279a2b12d1c 100644 --- a/docs/book/src/blockchain-development/access_control.md +++ b/docs/book/src/blockchain-development/access_control.md @@ -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` 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}} +``` diff --git a/examples/Forc.lock b/examples/Forc.lock index e399de8ac3c..92c264db602 100644 --- a/examples/Forc.lock +++ b/examples/Forc.lock @@ -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' @@ -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' @@ -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' @@ -136,7 +153,7 @@ source = 'member' [[package]] name = 'subcurrency' source = 'member' -dependencies = ['std'] +dependencies = ['std path+from-root-087D5D776F294F03'] [[package]] name = 'tuples' @@ -145,23 +162,23 @@ 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', ] @@ -169,6 +186,6 @@ dependencies = [ name = 'wallet_smart_contract' source = 'member' dependencies = [ - 'std', + 'std path+from-root-087D5D776F294F03', 'wallet_abi', ] diff --git a/examples/ownership/Forc.toml b/examples/ownership/Forc.toml index c4965df213e..28e12e0cb24 100644 --- a/examples/ownership/Forc.toml +++ b/examples/ownership/Forc.toml @@ -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" } diff --git a/examples/ownership/src/main.sw b/examples/ownership/src/main.sw index 92dee6f132a..9584c65ceef 100644 --- a/examples/ownership/src/main.sw +++ b/examples/ownership/src/main.sw @@ -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; + fn owner() -> State; + #[storage(read)] + fn only_owner(); } +// ANCHOR: set_owner_example_storage storage { - owner: Option = 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 { - storage.owner.read() + fn only_owner() { + storage.owner.only_owner(); + // Do stuff here } + // ANCHOR_END: only_owner_example }