A NEAR plugin enables multiple Accounts to share ownership of a contract
cargo test -- --nocapture
multi-ownable
can be addeded to your contract via a macro:
rs
// Arguments:
// 1. name of your contract
// 2. name of the field where the multi ownable state is stored
// 3. enum type for possible multisig calls
// 4. callback function to process completed multisig calls
crate::impl_multi_ownable!(Contract, multi_ownable, MultiOwnableCall, on_call);
Here is a full working example of how to use multi-ownable
```rs // import "implmultiownable" and "MultiOwnableData" use multiownable::{implmultiownable, MultiOwnableData}; use nearsdk::borsh::{self, BorshDeserialize, BorshSerialize}; use nearsdk::{env, nearbindgen, require, AccountId, BorshStorageKey, PanicOnDefault};
pub struct Contract { multi_ownable: MultiOwnableData, // add this to the Contract number: u64, }
enum StorageKey { Owners, MultiOwnableCalls, }
impl Contract { #[init] pub fn new(ownerid: AccountId) -> Self { let mut this = Self { number: 0, multiownable: MultiOwnableData::new(StorageKey::Owners, StorageKey::MultiOwnableCalls), }; // initialize multiownable in the "new" func of your Contract this.initmultiownable(vec![ownerid.clone()], 1); this }
pub fn get_number(&self) -> u64 { self.number }
// arguments are received as a json string fn oncall(&mut self, callname: MultiOwnableCall, arguments: &str) { match callname { MultiOwnableCall::UpdateNumber => self.updatenumber(arguments), MultiOwnableCall::DoSomethingElse => self.dosomethingelse(arguments), } }
#[private] fn updatenumber(&mut self, args: &str) { // first, deserialize your arguments let UpdateNumberArgs { number } = nearsdk::serdejson::from_str(&args).expect("Invalid SetRewardRateArgs"); self.number = number; }
#[private] fn dosomething_else(&self, _args: &str) { // do something else } }
// an argument struct for "update_number" call
pub struct UpdateNumberArgs { pub number: u64, }
// create an enum to match possible multisig calls // make sure to both "rename" and "alias" your fields to be snake_case
pub enum MultiOwnableCall { #[serde(rename = "updatenumber", alias = "updatenumber")] UpdateNumber, #[serde(rename = "dosomethingelse", alias = "dosomethingelse")] DoSomethingElse, }
crate::implmultiownable!(Contract, multiownable, MultiOwnableCall, oncall);
```