From 83dbfa00fdd365da0f8e2430be26b173f2311333 Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 11 Jan 2023 18:27:57 +0100 Subject: [PATCH 1/4] Update README.md --- README.md | 49 +++---------------------------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index d4683ed..1d8a0dc 100644 --- a/README.md +++ b/README.md @@ -15,54 +15,11 @@ The following sections provide an overview of all available plugins. More exampl ### [Ownable](/near-plugins/src/ownable.rs) -Basic access control mechanism that allows _only_ an authorized account id to call certain methods. Note this account -id can belong either to a regular user, or it could be a contract (a DAO for example). +Basic access control mechanism that allows _only_ an authorized account id to call certain methods. Note this account id can belong either to a regular user, or it could be a contract (a DAO for example). -Contract example using _Ownable_ plugin. +[This contract](/near-plugins/tests/contracts/ownable/src/lib.rs) provides an example of using `Ownable`. It is compiled, deployed on chain and interacted with in [integration tests](/near-plugins/tests/ownable.rs). -```rust -#[near_bindgen] -#[derive(Ownable)] -struct Counter { - counter: u64, -} - -#[near_bindgen] -impl Counter { - /// Specify the owner of the contract in the constructor - #[init] - fn new() -> Self { - let mut contract = Self { counter: 0 }; - contract.owner_set(Some(near_sdk::env::predecessor_account_id())); - contract - } - - /// Only owner account, or the contract itself can call this method. - #[only(self, owner)] - fn protected(&mut self) { - self.counter += 1; - } - - /// *Only* owner account can call this method. - #[only(owner)] - fn protected_owner(&mut self) { - self.counter += 1; - } - - /// *Only* self account can call this method. This can be used even if the contract is not Ownable. - #[only(self)] - fn protected_self(&mut self) { - self.counter += 1; - } - - /// Everyone can call this method - fn unprotected(&mut self) { - self.counter += 1; - } -} -``` - -Documentation of all methods provided by the derived implementation of `Ownable` is available in the [definition of the trait](/near-plugins/src/ownable.rs). More examples and guidelines for interacting with an `Ownable` contract can be found [here](/examples/ownable-examples/README.md). +Documentation of all methods provided by the derived implementation of `Ownable` is available in the [definition of the trait](/near-plugins/src/ownable.rs). ### [Full Access Key Fallback](/near-plugins/src/full_access_key_fallback.rs) From 2eba3164f4df413acb29d31a36046118960bd34a Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 11 Jan 2023 20:02:56 +0100 Subject: [PATCH 2/4] Remove ownable-examples README --- examples/ownable-examples/README.md | 305 ---------------------------- 1 file changed, 305 deletions(-) delete mode 100644 examples/ownable-examples/README.md diff --git a/examples/ownable-examples/README.md b/examples/ownable-examples/README.md deleted file mode 100644 index 3be283e..0000000 --- a/examples/ownable-examples/README.md +++ /dev/null @@ -1,305 +0,0 @@ -# Example of using Ownable plugin - -A basic access control mechanism that allows only an authorized account ID to call certain methods. Note, this account ID can belong either to a regular user, or it could be a contract (a DAO for example). - -```Rust -use near_plugins::Ownable; -use near_sdk::near_bindgen; -use near_plugins_derive::only; -use borsh::{BorshSerialize, BorshDeserialize}; - -#[near_bindgen] -#[derive(Ownable, Default, BorshSerialize, BorshDeserialize)] -struct Counter { - counter: u64, -} - -#[near_bindgen] -impl Counter { - /// Specify the owner of the contract in the constructor - #[init] - pub fn new() -> Self { - let mut contract = Self { counter: 0 }; - contract.owner_set(Some(near_sdk::env::predecessor_account_id())); - contract - } - - /// Only owner account, or the contract itself can call this method. - #[only(self, owner)] - pub fn protected(&mut self) { - self.counter += 1; - } - - /// *Only* owner account can call this method. - #[only(owner)] - pub fn protected_owner(&mut self) { - self.counter += 1; - } - - /// *Only* self account can call this method. This can be used even if the contract is not Ownable. - #[only(self)] - pub fn protected_self(&mut self) { - self.counter += 1; - } - - /// Everyone can call this method - pub fn unprotected(&mut self) { - self.counter += 1; - } - - /// View method returns the value of the counter. Everyone can call it - pub fn get_counter(&self) -> u64 { - self.counter - } -} -``` -## The contract methods description - -### owner_set -`owner_set` is the method that sets the new owner of the contract. Only the current owner of the contract can set a new one. -If the contract doesn't have any owner, the self can set one. - -```shell -$ near call owner_set '{"owner": }' --accountId -``` - -If the ownership transfer were successful following event will be emitted: -```json -{ - "standard":"Ownable", - "version":"1.0.0", - "event":"ownership_transferred", - "data": { - "previous_owner":"", - "new_owner":"" - } -} -``` - - -### owner_get -`owner_get` is the _view_ method, which returns the current contract owner. - -```shell -$ near view owner_get '{}' -View call: .owner_get({}) -'' -``` - -### owner_storage_key -`owner_storage_key` is the _view_ method that returns the key for storage, the owner account id. -The `__OWNER__` by default. It can be changed by using the `ownable` attribute. See example `ownable_change_storage_key`. - -```shell -$ near view owner_storage_key -View call: .owner_storage_key() -[ - 95, 95, 79, 87, 78, - 69, 82, 95, 95 -] -$ python3 ->>> print(' '.join(str(b) for b in bytes("__OWNER__", 'utf8'))) -95 95 79 87 78 69 82 95 95 -``` - -### owner_is -`owner_is` is the method that checks if the caller is the owner of the contract. - -```shell -$ near call owner_is --accountId -Scheduling a call: .testnet.owner_is() -Doing account.functionCall() -Transaction Id -To see the transaction in the transaction explorer, please open this url in your browser -https://explorer.testnet.near.org/transactions/ -true -``` - -## Example of using a contract with the ownable plugin -In that document, we are providing some examples of using contracts with the ownable plugin. You also can explore the usage examples in the tests in `ownable_base/src/lib.rs`. For running tests, please take a look at the **Test running instruction** section. - -### Preparation steps for demonstration -1. **Creating an account on testnet** - - For demonstration, we should create a few accounts on NEAR testnet. Let's say we will create two accounts on NEAR testnet: (1) ..testnet, (2) ..testnet. You should pick some unique names for accounts. - - The instruction of creating an accounts on NEAR testnet: https://docs.near.org/tools/near-cli#near-create-account - - ```shell - $ near create-account ..testnet --masterAccount .testnet --initialBalance 10 - $ near create-account ..testnet --masterAccount .testnet --initialBalance 10 - ``` - - In the next sections we will refer to the `..testnet` as `` and to the `..testnet` as `` for simplicity. - -2. **Compile Contract to wasm file** - For compiling the contract just run the `ownable_base/build.sh` script. The target file with compiled contract will be `../target/wasm32-unknown-unknown/release/ownable_base.wasm` - - ```shell - $ cd ownable_base - $ ./build.sh - $ cd .. - ``` - -3. **Deploy and init a contract** - ```shell - $ near deploy --accountId --wasmFile ../target/wasm32-unknown-unknown/release/ownable_base.wasm --initFunction new --initArgs '{}' - ``` - -### Contract with owner plugin usage examples -#### When the self is the owner it can call all methods -After initialization, the `` is the owner of this contract. So this account is both the `self` and the `owner` of the contract, and it can call all the contract methods. - -```shell -$ near call protected '{}' --accountId -$ near call protected_owner '{}' --accountId -$ near call protected_self '{}' --accountId -$ near call unprotected '{}' --accountId -``` - -We can check that we succeeded in calling all these functions by calling the `get_counter` view method and checking that the counter is 4. - -```shell -$ near view get_counter '{}' -View call: .get_counter({}) -4 -``` - -#### The stranger accounts can use only unprotected functions -Currently, the `` doesn't connected to the contract. So, we can check that we can only succeed in calling `unprotected` method and will fail on calling all other protected methods. - -```shell -$ near call protected '{}' --accountId -ERROR -$ near call protected_owner '{}' --accountId -ERROR -$ near call protected_self '{}' --accountId -ERROR -$ near view get_counter '{}' -View call: .get_counter({}) -4 -$ near call unprotected '{}' --accountId -$ near view get_counter '{}' -View call: .get_counter({}) -5 -``` - -#### Check and Change the contract owner -Let's change the contract owner from `` to ``. Only the current owner of the contract can change the owner. - -We can check the owner of the contract by calling `owner_get` view method. -```shell -$ near view owner_get '{}' -View call: .owner_get({}) -'' -``` - -In this case, the owner is ``. And we can change the contract owner by running `owner_set`. -```shell -$ near call owner_set '{"owner": }' --accountId -``` - -And we can check the contract owner one more time for making sure, that it is changed. -```shell -$ near view owner_get '{}' -View call: .owner_get({}) -'' -``` - -#### When the self is not owner it can't run the only(owner) functions -So, now `` is not the owner of our contract anymore. The `` can run the `unprotected`, `proteced_self`, `protected` and can't use the methods `protected_owner`. - -```shell -$ near call protected '{}' --accountId -$ near call unprotected '{}' --accountId -$ near call protected_self '{}' --accountId -$ near view get_counter '{}' -View call: .get_counter({}) -8 -$ near call protected_owner '{}' --accountId -ERROR -$ near view get_counter '{}' -View call: .get_counter({}) -8 -``` - -#### Owner can't run the only(self) functions -And the owner of the contract(``) can use the functions `protected`, `protected_owner` and `unprotected` and can not run the `protected_self` method. - -```shell -$ near call protected '{}' --accountId -$ near call unprotected '{}' --accountId -$ near call protected_owner '{}' --accountId -$ near view get_counter '{}' -View call: .get_counter({}) -11 -$ near call protected_self '{}' --accountId -ERROR -$ near view get_counter '{}' -View call: .get_counter({}) -11 -``` -#### Only owner can change the contract ownership -When the contract has an owner, only the owner can change the ownership. All other accounts, including self, can't. - -```shell -$ near view owner_get '{}' -View call: .owner_get({}) -'' -$ near call owner_set '{"owner": }' --accountId -ERROR -$ near view owner_get '{}' -View call: .owner_get({}) -'' - -``` - -#### Removing the owner of contract -We can remove the owner of the contract by set owner Null -```shell -$ near call owner_set '{"owner": null}' --accountId -$ near view owner_get '{}' -View call: .owner_get({}) -null -``` - -#### The self can't run the only(owner) function if contract doesn't have an owner -When the contract doesn't have an owner, no one can use `only(owner)` functions including self. - -```shell -$ near view get_counter '{}' -View call: .get_counter({}) -11 -$ near call protected_owner '{}' --accountId -ERROR -$ near view get_counter '{}' -View call: .get_counter({}) -11 -``` - -#### When the contract doesn't have owner, the self can set up a new one -When the contract doesn't have the owner, the self can set up a new owner. -```shell -$ near view owner_get '{}' -View call: .owner_get({}) -null -$ near call owner_set '{"owner": }' --accountId -$ near view owner_get '{}' -View call: .owner_get({}) -'' -``` - -### Tests running instruction -Tests in `ownable_base/src/lib.rs` contain examples of interaction with a contract. - -For running test: -1. Generate `wasm` file by running `build.sh` script. The target file will be `../target/wasm32-unknown-unknown/release/ownable_base.wasm` -2. Run tests `cargo test` - -```shell -$ cd ownable_base -$ ./build.sh -$ cargo test -``` - -For tests, we use `workspaces` library and `sandbox` environment. For details, you can explore `../near-plugins-test-utils` crate. \ No newline at end of file From 13132a01718be9489f35b88c71d2bfc88b7cfff4 Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 11 Jan 2023 20:08:52 +0100 Subject: [PATCH 3/4] Extend docs of `Ownable` trait --- near-plugins/src/ownable.rs | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/near-plugins/src/ownable.rs b/near-plugins/src/ownable.rs index ab62615..2471d3d 100644 --- a/near-plugins/src/ownable.rs +++ b/near-plugins/src/ownable.rs @@ -17,24 +17,46 @@ use serde::Serialize; /// Trait describing the functionality of the _Ownable_ plugin. pub trait Ownable { - /// Key of storage slot to save the current owner. - /// By default b"__OWNER__" is used. + /// Returns the key of storage slot to save the current owner. By default b"__OWNER__" is used. + /// + /// Attribute `owner_storage_key` can be used to set a different key: + /// + /// ```ignore + /// #[ownable(owner_storage_key="CUSTOM_KEY")] + /// struct Contract { /* ... */} + /// ``` fn owner_storage_key(&self) -> Vec; - /// Return the current owner of the contract. Result must be a NEAR valid account id - /// or None, in case the account doesn't have an owner. + /// Returns the current owner of the contract. Result must be a NEAR valid account id or None, + /// in case the account doesn't have an owner. fn owner_get(&self) -> Option; - /// Replace the current owner of the contract by a new owner. Triggers an event of type - /// OwnershipTransferred. Use `None` to remove the owner of the contract all together. + /// Replaces the current owner of the contract by a new owner. Use `None` to remove the owner of + /// the contract. /// /// # Default Implementation: /// /// Only the current owner can call this method. If no owner is set, only self can call this /// method. Notice that if the owner is set, self will not be able to call `owner_set` by default. + /// + /// # Event + /// + /// If ownership is successfully transferred, the following event will be emitted: + /// + /// ```json + /// { + /// "standard": "Ownable", + /// "version": "1.0.0", + /// "event": "ownership_transferred", + /// "data": { + /// "previous_owner": "Option", + /// "new_owner": "Option" + /// } + /// } + /// ``` fn owner_set(&mut self, owner: Option); - /// Return true if the predecessor account id is the owner of the contract. + /// Returns true if the predecessor account id is the owner of the contract. /// /// # View calls /// From f1bb8468a0d9aadf89604ef84ed5c012d5f03b87 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 12 Jan 2023 08:44:24 +0100 Subject: [PATCH 4/4] Remove ownable-examples tests --- .../ownable-examples/ownable_base/Cargo.toml | 24 --- .../ownable-examples/ownable_base/build.sh | 7 - .../ownable-examples/ownable_base/src/lib.rs | 141 ------------------ .../ownable_change_storage_key/Cargo.toml | 23 --- .../ownable_change_storage_key/build.sh | 7 - .../ownable_change_storage_key/src/lib.rs | 67 --------- .../ownable_cross_call/Cargo.toml | 23 --- .../ownable_cross_call/build.sh | 7 - .../ownable_cross_call/src/lib.rs | 111 -------------- 9 files changed, 410 deletions(-) delete mode 100644 examples/ownable-examples/ownable_base/Cargo.toml delete mode 100755 examples/ownable-examples/ownable_base/build.sh delete mode 100644 examples/ownable-examples/ownable_base/src/lib.rs delete mode 100644 examples/ownable-examples/ownable_change_storage_key/Cargo.toml delete mode 100755 examples/ownable-examples/ownable_change_storage_key/build.sh delete mode 100644 examples/ownable-examples/ownable_change_storage_key/src/lib.rs delete mode 100644 examples/ownable-examples/ownable_cross_call/Cargo.toml delete mode 100755 examples/ownable-examples/ownable_cross_call/build.sh delete mode 100644 examples/ownable-examples/ownable_cross_call/src/lib.rs diff --git a/examples/ownable-examples/ownable_base/Cargo.toml b/examples/ownable-examples/ownable_base/Cargo.toml deleted file mode 100644 index 8201bda..0000000 --- a/examples/ownable-examples/ownable_base/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "ownable_base" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -near-sdk = "4.0.0" -near-plugins = { path = "../../../near-plugins" } -near-plugins-derive = { path = "../../../near-plugins-derive" } -borsh = "0.9.3" - -[dev-dependencies] -near-primitives = "0.14.0" -workspaces = "0.6" -tokio = { version = "1.1", features = ["rt", "macros"] } -serde_json = "1.0.74" -near-plugins-test-utils = { path = "../../near-plugins-test-utils" } - - diff --git a/examples/ownable-examples/ownable_base/build.sh b/examples/ownable-examples/ownable_base/build.sh deleted file mode 100755 index 7f2cc33..0000000 --- a/examples/ownable-examples/ownable_base/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p ../../res - -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release - -cp ../../target/wasm32-unknown-unknown/release/ownable_base.wasm ../../res/ \ No newline at end of file diff --git a/examples/ownable-examples/ownable_base/src/lib.rs b/examples/ownable-examples/ownable_base/src/lib.rs deleted file mode 100644 index 0d61f33..0000000 --- a/examples/ownable-examples/ownable_base/src/lib.rs +++ /dev/null @@ -1,141 +0,0 @@ -use near_plugins::Ownable; -use near_sdk::near_bindgen; -use near_plugins_derive::only; -use borsh::{BorshSerialize, BorshDeserialize}; - -#[near_bindgen] -#[derive(Ownable, Default, BorshSerialize, BorshDeserialize)] -struct Counter { - counter: u64, -} - -#[near_bindgen] -impl Counter { - /// Specify the owner of the contract in the constructor - #[init] - pub fn new() -> Self { - let mut contract = Self { counter: 0 }; - contract.owner_set(Some(near_sdk::env::predecessor_account_id())); - contract - } - - /// Only owner account, or the contract itself can call this method. - #[only(self, owner)] - pub fn protected(&mut self) { - self.counter += 1; - } - - /// *Only* owner account can call this method. - #[only(owner)] - pub fn protected_owner(&mut self) { - self.counter += 1; - } - - /// *Only* self account can call this method. This can be used even if the contract is not Ownable. - #[only(self)] - pub fn protected_self(&mut self) { - self.counter += 1; - } - - /// Everyone can call this method - pub fn unprotected(&mut self) { - self.counter += 1; - } - - /// View method returns the value of the counter. Everyone can call it - pub fn get_counter(&self) -> u64 { - self.counter - } -} - - -#[cfg(test)] -mod tests { - use serde_json::json; - use near_sdk::AccountId; - use near_plugins_test_utils::*; - - const WASM_FILEPATH: &str = "../../target/wasm32-unknown-unknown/release/ownable_base.wasm"; - - #[tokio::test] - async fn base_scenario() { - let (contract_holder, contract) = get_contract(WASM_FILEPATH).await; - - assert!(call!(contract, "new").await); - - let current_owner: Option:: = view!(contract, "owner_get"); - assert_eq!(current_owner.unwrap().as_str(), contract_holder.id().as_str()); - - check_counter(&contract, 0).await; - - assert!(call!(contract, "protected").await); - assert!(call!(contract, "protected_owner").await); - assert!(call!(contract, "protected_self").await); - assert!(call!(contract, "unprotected").await); - - check_counter(&contract, 4).await; - - let next_owner = get_subaccount(&contract_holder, "next_owner").await; - assert!(!call!(&next_owner, contract, "protected").await); - assert!(!call!(&next_owner, contract, "protected_owner").await); - assert!(!call!(&next_owner, contract, "protected_self").await); - assert!(call!(&next_owner, contract, "unprotected").await); - - check_counter(&contract, 5).await; - - assert!(call_arg(&contract, "owner_set", &json!({"owner": next_owner.id()})).await); - - let current_owner: Option:: = view!(contract, "owner_get"); - assert_ne!(current_owner.clone().unwrap().as_str(), contract_holder.id().as_str()); - assert_eq!(current_owner.unwrap().as_str(), next_owner.id().as_str()); - - assert!(call!(&next_owner, contract, "protected").await); - assert!(call!(&next_owner, contract, "protected_owner").await); - assert!(!call!(&next_owner, contract, "protected_self").await); - assert!(call!(&next_owner, contract, "unprotected").await); - - check_counter(&contract, 8).await; - - assert!(call!(contract, "protected").await); - assert!(!call!(contract, "protected_owner").await); - assert!(call!(contract, "protected_self").await); - assert!(call!(contract, "unprotected").await); - - check_counter(&contract, 11); - } - - #[tokio::test] - async fn null_owner() { - let (_, contract) = get_contract(WASM_FILEPATH).await; - assert!(call!(contract,"new").await); - - assert!(call!(contract, "owner_set", &json!({"owner": Option::::None})).await); - - let current_owner: Option:: = view!(contract, "owner_get"); - assert_eq!(current_owner, None); - - assert!(call!(contract, "protected").await); - assert!(!call!(contract, "protected_owner").await); - assert!(call!(contract, "protected_self").await); - assert!(call!(contract, "unprotected").await); - - check_counter(&contract, 3).await; - - assert!(call!(contract, "owner_set", &json!({"owner": contract.id().as_str()})).await); - assert!(call!(contract, "protected").await); - assert!(call!(contract, "protected_owner").await); - assert!(call!(contract, "protected_self").await); - assert!(call!(contract, "unprotected").await); - - check_counter(&contract, 7).await; - } - - #[tokio::test] - async fn check_owner_storage_key() { - let (_, contract) = get_contract(WASM_FILEPATH).await; - assert!(call!(contract,"new").await); - - let owner_storage_key: Vec = view!(contract, "owner_storage_key"); - assert_eq!(owner_storage_key, "__OWNER__".as_bytes().to_vec()); - } -} diff --git a/examples/ownable-examples/ownable_change_storage_key/Cargo.toml b/examples/ownable-examples/ownable_change_storage_key/Cargo.toml deleted file mode 100644 index 8d39ab1..0000000 --- a/examples/ownable-examples/ownable_change_storage_key/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "ownable_change_storage_key" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -near-sdk = "4.0.0" -near-plugins = { path = "../../../near-plugins" } -near-plugins-derive = { path = "../../../near-plugins-derive" } -borsh = "0.9.3" - -[dev-dependencies] -near-primitives = "0.14.0" -workspaces = "0.6" -tokio = { version = "1.1", features = ["rt", "macros"] } -serde_json = "1.0.74" -near-plugins-test-utils = { path = "../../near-plugins-test-utils" } - diff --git a/examples/ownable-examples/ownable_change_storage_key/build.sh b/examples/ownable-examples/ownable_change_storage_key/build.sh deleted file mode 100755 index f41c331..0000000 --- a/examples/ownable-examples/ownable_change_storage_key/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p ../../res - -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release - -cp ../../target/wasm32-unknown-unknown/release/ownable_change_storage_key.wasm ../../res/ \ No newline at end of file diff --git a/examples/ownable-examples/ownable_change_storage_key/src/lib.rs b/examples/ownable-examples/ownable_change_storage_key/src/lib.rs deleted file mode 100644 index c8740f2..0000000 --- a/examples/ownable-examples/ownable_change_storage_key/src/lib.rs +++ /dev/null @@ -1,67 +0,0 @@ -use near_plugins::Ownable; -use near_sdk::near_bindgen; -use near_plugins_derive::only; -use borsh::{BorshSerialize, BorshDeserialize}; - -#[near_bindgen] -#[derive(Ownable, Default, BorshSerialize, BorshDeserialize)] -#[ownable(owner_storage_key="new_storage_key")] -struct Counter { - counter: u64, -} - -#[near_bindgen] -impl Counter { - /// Specify the owner of the contract in the constructor - #[init] - pub fn new() -> Self { - let mut contract = Self { counter: 0 }; - contract.owner_set(Some(near_sdk::env::predecessor_account_id())); - contract - } - - /// Only owner account, or the contract itself can call this method. - #[only(self, owner)] - pub fn protected(&mut self) { - self.counter += 1; - } - - /// *Only* owner account can call this method. - #[only(owner)] - pub fn protected_owner(&mut self) { - self.counter += 1; - } - - /// *Only* self account can call this method. This can be used even if the contract is not Ownable. - #[only(self)] - pub fn protected_self(&mut self) { - self.counter += 1; - } - - /// Everyone can call this method - pub fn unprotected(&mut self) { - self.counter += 1; - } - - pub fn get_counter(&self) -> u64 { - self.counter - } -} - - -#[cfg(test)] -mod tests { - use serde_json::json; - use near_plugins_test_utils::*; - - const WASM_FILEPATH: &str = "../../target/wasm32-unknown-unknown/release/ownable_change_storage_key.wasm"; - - #[tokio::test] - async fn check_owner_storage_key() { - let (_, contract) = get_contract(WASM_FILEPATH).await; - assert!(call!(contract,"new").await); - - let owner_storage_key: Vec = view!(contract, "owner_storage_key"); - assert_eq!(owner_storage_key, "new_storage_key".as_bytes().to_vec()); - } -} diff --git a/examples/ownable-examples/ownable_cross_call/Cargo.toml b/examples/ownable-examples/ownable_cross_call/Cargo.toml deleted file mode 100644 index e6096ab..0000000 --- a/examples/ownable-examples/ownable_cross_call/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "ownable_cross_call" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -near-sdk = "4.0.0" -near-plugins = { path = "../../../near-plugins" } -near-plugins-derive = { path = "../../../near-plugins-derive" } -borsh = "0.9.3" - -[dev-dependencies] -near-primitives = "0.14.0" -workspaces = "0.6" -tokio = { version = "1.1", features = ["rt", "macros"] } -serde_json = "1.0.74" -near-plugins-test-utils = { path = "../../near-plugins-test-utils" } - diff --git a/examples/ownable-examples/ownable_cross_call/build.sh b/examples/ownable-examples/ownable_cross_call/build.sh deleted file mode 100755 index 6afc0e1..0000000 --- a/examples/ownable-examples/ownable_cross_call/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p ../../res - -RUSTFLAGS='-C link-arg=-s' cargo build --target wasm32-unknown-unknown --release - -cp ../../target/wasm32-unknown-unknown/release/ownable_cross_call.wasm ../../res/ \ No newline at end of file diff --git a/examples/ownable-examples/ownable_cross_call/src/lib.rs b/examples/ownable-examples/ownable_cross_call/src/lib.rs deleted file mode 100644 index 6d2cd9b..0000000 --- a/examples/ownable-examples/ownable_cross_call/src/lib.rs +++ /dev/null @@ -1,111 +0,0 @@ -use near_plugins::Ownable; -use near_sdk::{env, near_bindgen}; -use near_sdk::ext_contract; -use near_plugins_derive::only; -use borsh::{BorshSerialize, BorshDeserialize}; - -#[ext_contract(ext_counter)] -pub trait ExtCounter { - fn protected_self(&mut self); - fn protected_owner(&mut self); -} - -#[near_bindgen] -#[derive(Ownable, Default, BorshSerialize, BorshDeserialize)] -struct Counter { - counter: u64, -} - -#[near_bindgen] -impl Counter { - /// Specify the owner of the contract in the constructor - #[init] - pub fn new() -> Self { - let mut contract = Self { counter: 0 }; - contract.owner_set(Some(near_sdk::env::predecessor_account_id())); - contract - } - - /// Only owner account, or the contract itself can call this method. - #[only(self, owner)] - pub fn protected(&mut self) { - self.counter += 1; - } - - /// *Only* owner account can call this method. - #[only(owner)] - pub fn protected_owner(&mut self) { - self.counter += 1; - } - - /// *Only* self account can call this method. This can be used even if the contract is not Ownable. - #[only(self)] - pub fn protected_self(&mut self) { - self.counter += 1; - } - - /// Everyone can call this method - pub fn unprotected(&mut self) { - self.counter += 1; - } - - #[only(owner)] - pub fn cross_call_owner_self(&mut self) { - ext_counter::ext(env::current_account_id()).protected_self(); - } - - #[only(self)] - pub fn cross_call_self_owner(&mut self) { - ext_counter::ext(env::current_account_id()).protected_owner(); - } - - #[only(owner)] - pub fn cross_call_owner_owner(&mut self) { - ext_counter::ext(env::current_account_id()).protected_owner(); - } - - #[only(self)] - pub fn cross_call_self_self(&mut self) { - ext_counter::ext(env::current_account_id()).protected_self(); - } - - pub fn get_counter(&self) -> u64 { - self.counter - } -} - - -#[cfg(test)] -mod tests { - use serde_json::json; - use near_sdk::AccountId; - use near_plugins_test_utils::*; - - const WASM_FILEPATH: &str = "../../target/wasm32-unknown-unknown/release/ownable_cross_call.wasm"; - - #[tokio::test] - async fn base_scenario() { - let (contract_holder, contract) = get_contract(WASM_FILEPATH).await; - - assert!(call!(contract,"new").await); - let next_owner = get_subaccount(&contract_holder, "next_owner").await; - assert!(call!(contract, "owner_set", &json!({"owner": next_owner.id()})).await); - let current_owner: Option:: = view!(contract, "owner_get"); - assert_ne!(current_owner.clone().unwrap().as_str(), contract_holder.id().as_str()); - assert_eq!(current_owner.unwrap().as_str(), next_owner.id().as_str()); - - assert!(call!(&next_owner, contract, "cross_call_owner_self").await); - assert!(call!(&next_owner, contract, "cross_call_owner_owner").await); - assert!(!call!(&next_owner, contract, "cross_call_self_self").await); - assert!(!call!(&next_owner, contract, "cross_call_self_owner").await); - - check_counter(&contract, 1).await; - - assert!(!call!(contract, "cross_call_owner_self").await); - assert!(!call!(contract, "cross_call_owner_owner").await); - assert!(call!(contract, "cross_call_self_self").await); - assert!(call!(contract, "cross_call_self_owner").await); - - check_counter(&contract, 2).await; - } -}