near / near-sdk-contract-tools

Helpful functions and macros for developing smart contracts on NEAR Protocol.
https://crates.io/crates/near-sdk-contract-tools
Apache License 2.0
41 stars 12 forks source link

Identities component #88

Open encody opened 2 years ago

encody commented 2 years ago

Like a generic version of Owner. Like Rbac, but there is a 1:0..1 relationship between an identity and an account ID. It will also be possible to retrieve the holder of an identity (enumeration is not possible in the current version of Rbac). Identity transfer (via propose/accept) and renunciation are optionally allowed.

Possible Example

enum Identity {
    Owner,
    Administrator,
    Manager,
}

#[derive(Identities)]
#[identities(identities = "Identity")]
#[near_bindgen]
struct MyContract {}

#[near_bindgen]
impl MyContract {
    #[init]
    fn init() -> Self {
        let mut contract = Self {};

        contract.initialize_identity(&Identity::Owner, env::predecessor_account_id());
        contract.initialize_identity(&Identity::Administrator, env::predecessor_account_id());
        contract.initialize_identity(&Identity::Manager, env::predecessor_account_id());
    }

    fn only_owner(&self, account: AccountId) {
        self.require_identity(&Identity::Owner);
    }

    fn only_administrator(&self, account: AccountId) {
        self.require_identity(&Identity::Administrator);
    }
}

impl IdentityHook<Identity> for MyContract {
    fn on_transfer(identity: &Identity, from: AccountId, to: AccountId) -> Result<(), ?> { }

    fn on_propose(identity: &Identity, account: AccountId) -> Result<(), ?> { }

    fn on_accept(identity: &Identity, account: AccountId) -> Result<(), ?> { }
}

Would expose the following interface to the blockchain:

(Caveat: Identities need a to/from string serialization)

trait IdentityExternal<Identity> {
    fn id_is(&self, account: AccountId, identity: Identity) -> bool;
    fn id_get(&self, identity: Identity) -> Option<AccountId>;
    fn id_renounce(&mut self, identity: Identity);
    fn id_propose(&mut self, identity: Identity, to: AccountId);
    fn id_accept(&mut self, identity: Identity, from: AccountId);
}
encody commented 2 years ago

Alternatively: extend/generalize the Rbac component to support these features.