Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permission token examples #467

Merged
2 changes: 1 addition & 1 deletion src/guide/blockchain/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Similar to mint and burn instructions, transferring refers to assets. You
can transfer assets between different accounts.

To do this, an account have to be granted the
[permission to transfer assets](/reference/permissions.md#cantransferuserassets).
[permission to transfer assets](/reference/permissions.md).
Refer to an example on how to
[transfer assets in Bash](/guide/get-started/bash.md#_6-transferring-assets).

Expand Down
11 changes: 2 additions & 9 deletions src/guide/blockchain/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,5 @@ You can get the key value of an object metadata using

## Permissions

Pre-configured tokens in Iroha 2 LTS version that allow to set or remove
key-values in accounts, assets, or asset definitions:

- [`CanSetKeyValueInUserMetadata`](/reference/permissions.md#cansetkeyvalueinusermetadata)
- [`CanRemoveKeyValueInUserMetadata`](/reference/permissions.md#canremovekeyvalueinusermetadata)
- [`CanSetKeyValueInUserAssets`](/reference/permissions.md#cansetkeyvalueinuserassets)
- [`CanRemoveKeyValueInUserAssets`](/reference/permissions.md#canremovekeyvalueinuserassets)
- [`CanSetKeyValueInAssetDefinition`](/reference/permissions.md#cansetkeyvalueinassetdefinition)
- [`CanRemoveKeyValueInAssetDefinition`](/reference/permissions.md#canremovekeyvalueinassetdefinition)
Pre-configured tokens in Iroha 2 that allow to set or remove
key-values in accounts, assets, asset definitions, and so on are described in [`Permissions`](/reference/permissions.md).
357 changes: 52 additions & 305 deletions src/reference/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,319 +6,66 @@ This section provides details about pre-configured permission tokens in Iroha 2.

The following permission tokens are pre-configured in Iroha 2:

| Permission Token | Category | Operation |
| ------------------------------------------------------------------------------------------- | ---------------- | ---------------- |
| [`CanSetKeyValueInUserMetadata`](#cansetkeyvalueinusermetadata) | Account | Set key value |
| [`CanRemoveKeyValueInUserMetadata`](#canremovekeyvalueinusermetadata) | Account | Remove key value |
| [`CanBurnUserAssets`](#canburnuserassets) | Asset | Burn |
| [`CanSetKeyValueInUserAssets`](#cansetkeyvalueinuserassets) | Asset | Set key value |
| [`CanRemoveKeyValueInUserAssets`](#canremovekeyvalueinuserassets) | Asset | Remove key value |
| [`CanTransferUserAssets`](#cantransferuserassets) | Asset | Transfer |
| [`CanTransferOnlyFixedNumberOfTimesPerPeriod`](#cantransferonlyfixednumberoftimesperperiod) | Asset | Transfer |
| [`CanMintUserAssetDefinitions`](#canmintuserassetdefinitions) | Asset Definition | Mint |
| [`CanBurnAssetWithDefinition`](#canburnassetwithdefinition) | Asset Definition | Burn |
| [`CanUnregisterAssetWithDefinition`](#canunregisterassetwithdefinition) | Asset Definition | Unregister |
| [`CanSetKeyValueInAssetDefinition`](#cansetkeyvalueinassetdefinition) | Asset Definition | Set key value |
| [`CanRemoveKeyValueInAssetDefinition`](#canremovekeyvalueinassetdefinition) | Asset Definition | Remove key value |
| [`CanRegisterDomains`](#canregisterdomains) | Domain | Register |
| Permission Token | Category | Operation |
|-----------------------------------------|------------------|--------------------------------------------------------------------|
| [`CanUnregisterDomain`] | Domain | Allows to unregister a domain |
| [`CanSetKeyValueInDomain`] | Domain | Allows to add domain's metadata key value |
| [`CanRemoveKeyValueInDomain`] | Domain | Allows to remove domain's metadata key value |
| [`CanUnregisterAccount`] | Account | Allows to unregister an account |
| [`CanMintUserPublicKeys`] | Account | Allows to add a public key to an account |
| [`CanBurnUserPublicKeys`] | Account | Allows to remove a public key from an account |
| [`CanMintUserSignatureCheckConditions`] | Account | Allows to set check conditions for a signature |
| [`CanSetKeyValueInUserAccount`] | Account | Allows to add user's metadata key value |
| [`CanRemoveKeyValueInUserAccount`] | Account | Allows to remove user's metadata key value |
| [`CanRegisterAssetsWithDefinition`] | Asset | Allows to register a new asset with this definition |
| [`CanUnregisterAssetsWithDefinition`] | Asset | Allows to unregister a new asset with this definition |
| [`CanUnregisterUserAsset`] | Asset | Allows to remove asset from a user |
| [`CanMintAssetsWithDefinition`] | Asset | Allows to mint quantity of assets with this definition |
| [`CanBurnAssetsWithDefinition`] | Asset | Allows to burn quantity of assets with this definition |
| [`CanTransferAssetsWithDefinition`] | Asset | Allows to transfer quantity of assets with this definition |
| [`CanBurnUserAsset`] | Asset | Allows to burn user's asset quantity |
| [`CanTransferUserAsset`] | Asset | Allows to transfer user's asset quantity |
| [`CanSetKeyValueInUserAsset`] | Asset | Allows to set key value to user's asset metadata |
| [`CanRemoveKeyValueInUserAsset`] | Asset | Allows to remove key value from user's asset metadata |
| [`CanSetKeyValueInAssetDefinition`] | Asset Definition | Allows to add key value to metadata for this asset definition |
| [`CanRemoveKeyValueInAssetDefinition`] | Asset Definition | Allows to remove key value from metadata for this asset definition |
| [`CanUnregisterAssetDefinition`] | Asset Definition | Allows to unregister this asset definition |

::: info

The way permission work in Iroha 2 is subject to change. Note that there
won't be pre-configured permissions in the future.
The way permissions work in Iroha 2 is subject to change.
Only an owner of the subject can grant permissions for the subject.

:::

### `CanMintUserAssetDefinitions`

With `CanMintUserAssetDefinitions`, a user can register and mint assets
with the corresponding asset definition.

```rust
let mut genesis = RawGenesisBlock::new(
"alice".parse(),
"wonderland".parse(),
get_key_pair().public_key().clone(),
);
let rose_definition_id =
AssetDefinitionId::from_str("rose#wonderland")?;
let alice_id =
AccountId::from_str("alice@wonderland")?;

// Create a new `CanMintUserAssetDefinitions` permission token
// to mint rose assets (`rose_definition_id`)
let mint_rose_permission: PermissionToken =
CanMintUserAssetDefinitions::new(rose_definition_id).into();

// Grant Alice permission to mint rose assets
genesis.transactions[0]
.isi
.push(GrantBox::new(mint_rose_permission, alice_id).into());
```

### `CanBurnAssetWithDefinition`

With `CanBurnAssetWithDefinition` permission token, a user can burn and
unregister assets with the corresponding asset definition.

```rust
let mut genesis = RawGenesisBlock::new(
"alice".parse(),
"wonderland".parse(),
get_key_pair().public_key().clone(),
);
let rose_definition_id =
AssetDefinitionId::from_str("rose#wonderland")?;
let alice_id =
AccountId::from_str("alice@wonderland")?;

// Create a new `CanBurnAssetWithDefinition` permission token
// to burn rose assets (`rose_definition_id`)
let burn_rose_permission: PermissionToken =
CanBurnAssetWithDefinition::new(rose_definition_id).into();

// Grant Alice permission to burn rose assets
genesis.transactions[0]
.isi
.push(GrantBox::new(burn_rose_permission, alice_id).into());
```

### `CanBurnUserAssets`

With `CanBurnUserAssets` permission token, a user can burn the specified
asset.

```rust
let alice_id = AccountId::from_str("alice@test")?;
let bob_id = AccountId::from_str("bob@test")?;
let alice_xor_id = AssetId::new(
AssetDefinitionId::from_str("xor#test")?,
AccountId::from_str("alice@test")?,
);

// Create a new `CanBurnUserAssets` permission token
// that allows burning `alice_xor_id` asset
let permission_token_to_alice: PermissionToken =
burn::CanBurnUserAssets::new(alice_xor_id).into();

// Create an instruction that grants Bob permission to burn `alice_xor_id` asset
let grant = Instruction::Grant(GrantBox::new(
permission_token_to_alice,
IdBox::AccountId(bob_id),
));
```

### `CanUnregisterAssetWithDefinition`

With `CanUnregisterAssetWithDefinition` permission token, a user can
unregister assets with the corresponding asset definition.

```rust
let alice_id = AccountId::from_str("alice@test")?;
let bob_id = AccountId::from_str("bob@test")?;
let xor_id = AssetDefinitionId::from_str("xor#test")?;

// Create a new `CanUnregisterAssetWithDefinition` permission token
// that allows unregistering `xor_id` asset
let permission_token_to_alice: PermissionToken =
unregister::CanUnregisterAssetWithDefinition::new(xor_id).into();

// Create an instruction that grants Bob permission to unregister `xor_id` asset
let grant = Instruction::Grant(GrantBox {
permission_token_to_alice.into(),
IdBox::AccountId(bob_id).into(),
});
```

### `CanTransferUserAssets`

With `CanTransferUserAssets` permission token, a user can transfer the
specified asset.

```rust
let alice_id = AccountId::from_str("alice@test")?;
let bob_id = AccountId::from_str("bob@test")?;
let alice_xor_id = AssetId::new(
AssetDefinitionId::from_str("xor#test")?,
AccountId::from_str("alice@test")?,
);

// Create a new `CanTransferUserAssets` permission token
// that allows to transfer `alice_xor_id` asset
let permission_token_to_alice: PermissionToken =
transfer::CanTransferUserAssets::new(alice_xor_id).into();

// Create an instruction that grants Bob permission to transfer `alice_xor_id` asset
let grant = Instruction::Grant(GrantBox::new(
permission_token_to_alice,
IdBox::AccountId(bob_id),
));
```

### `CanTransferOnlyFixedNumberOfTimesPerPeriod`

With `CanTransferOnlyFixedNumberOfTimesPerPeriod` permission token, a user
can transfer assets only a fixed number of times per some time period.

```rust
const PERIOD_MS: u64 = 5000;
const COUNT: u32 = 2;
By default, all assets and accounts defined in the genesis block configuration file are created by `genesis@genesis` account.
This means that `alice@wonderland` is not the owner of `rose#wonderland` and cannot grant permission for `rose#wonderland`.

// Create a new `CanTransferOnlyFixedNumberOfTimesPerPeriod` permission token
// that limits the number of transfer to 2 per 5000 ms.
let permission_token =
transfer::CanTransferOnlyFixedNumberOfTimesPerPeriod::new(PERIOD_MS.into(), COUNT);
```
To avoid this you can:
1. Edit the `genesis.json` file to only include the creation of `alice@wonderland`, and then redeploy Iroha 2.
2. Create a subject (e.g., an asset definition) on behalf of `alice@wonderland`, and then give another account the permission to manage this subject.

### `CanSetKeyValueInUserAssets`

With `CanSetKeyValueInUserAssets` permission token, a user can set key
value in the specified asset.

```rust
let bob_id = AccountId::from_str("bob@test")?;
let alice_id = AccountId::from_str("alice@test")?;
let alice_xor_id = AssetId::new(
AssetDefinitionId::from_str("xor#test")?,
AccountId::from_str("alice@test")?,
);

// Create a new `CanSetKeyValueInUserAssets` permission token
// that allows to set key value in `alice_xor_id` asset
let permission_to_set_key_value_in_xor: PermissionToken =
key_value::CanSetKeyValueInUserAssets::new(alice_xor_id).into();

// Create an instruction that grants Bob permission
// to set key value in `alice_xor_id` asset
let grant = Instruction::Grant(GrantBox::new(
permission_to_set_key_value_in_xor,
IdBox::AccountId(bob_id),
));
```

### `CanRemoveKeyValueInUserAssets`

With `CanRemoveKeyValueInUserAssets` permission token, a user can remove
key value in the specified asset.

```rust
let bob_id = AccountId::from_str("bob@test")?;
let alice_id = AccountId::from_str("alice@test")?;
let alice_xor_id = AssetId::new(
AssetDefinitionId::from_str("xor#test")?,
AccountId::from_str("alice@test")?,
);

// Create a new `CanRemoveKeyValueInUserAssets` permission token
// that allows to remove key value from `alice_xor_id` asset
let permission_to_set_key_value_in_xor: PermissionToken =
key_value::CanRemoveKeyValueInUserAssets::new(alice_xor_id).into();

// Create an instruction that grants Bob permission
// to remove key value from `alice_xor_id` asset
let grant = Instruction::Grant(GrantBox::new(
permission_to_set_key_value_in_xor,
IdBox::AccountId(bob_id),
```

### `CanSetKeyValueInUserMetadata`

With `CanSetKeyValueInUserMetadata` permission token, a user can set a key
value pair in the [metadata](/guide/blockchain/metadata.md) for the
specified account.

```rust
let mouse_id = AccountId::from_str("mouse@wonderland")?;

// Create a new `CanSetKeyValueInUserMetadata` token that, when granted to another account,
// allows it to set key value to the metadata in Mouse's account
let permission_to_set_key_value_in_mouse_metadata: PermissionToken =
key_value::CanSetKeyValueInUserMetadata::new(mouse_id).into();
```

### `CanRemoveKeyValueInUserMetadata`

With `CanRemoveKeyValueInUserMetadata` permission token, a user can remove
a key value pair in the [metadata](/guide/blockchain/metadata.md) for the
specified account.

```rust
let mouse_id = AccountId::from_str("mouse@wonderland")?;

// Create a new `CanRemoveKeyValueInUserMetadata` token that, when granted to another account,
// allows it to remove key value from the metadata in Mouse's account
let permission_to_remove_key_value_in_mouse_metadata: PermissionToken =
key_value::CanRemoveKeyValueInUserMetadata::new(mouse_id).into();
```

### `CanSetKeyValueInAssetDefinition`

With `CanSetKeyValueInAssetDefinition` permission token, a user can set key
value in the corresponding asset definition.

```rust
let bob_id = AccountId::from_str("bob@test")?;
let alice_id = AccountId::from_str("alice@test")?;
let alice_xor_id = AssetId::new(
AssetDefinitionId::from_str("xor#test")?,
AccountId::from_str("alice@test")?,
);

// Create a new `CanSetKeyValueInAssetDefinition` permission token
// that allows to set key value in `alice_xor_id` asset definition
let permission_to_set_key_value_in_xor: PermissionToken =
key_value::CanSetKeyValueInAssetDefinition::new(alice_xor_id).into();

// Create an instruction that grants Bob permission
// to set key value in `alice_xor_id` asset definition
let grant = Instruction::Grant(GrantBox::new(
permission_to_set_key_value_in_xor,
IdBox::AccountId(bob_id),
));
```
:::

### `CanRemoveKeyValueInAssetDefinition`
### `General example`

With `CanRemoveKeyValueInAssetDefinition` permission token, a user can
remove key value in the corresponding asset definition.
With this example, the owner-account can give permission for its subject to another account.
The example is based on the following pre-conditions:
The subject is created by the owner-account
The recipient account is created
Stukalov-A-M marked this conversation as resolved.
Show resolved Hide resolved

```rust
let bob_id = AccountId::from_str("bob@test")?;
let alice_id = AccountId::from_str("alice@test")?;
let alice_xor_id = AssetId::new(
AssetDefinitionId::from_str("xor#test")?,
AccountId::from_str("alice@test")?,
// Define the asset definition owner
let asset_definition_owner = AccountId::from_str("alice@wonderland").unwrap();
// Define the asset definition id which was created by the owner
let asset_definition_id = AssetDefinitionId::from_str("coolAsset#wonderland").unwrap();
// Define the account which we want to give the permission
let recipient_account = AccountId::from_str("actor@wonderland").unwrap();
// Create a token that we chose. And define its structure according to `iroha_executor\smart_contract\executor\src\default.rs`
let can_mint_asset_with_definition_token = PermissionToken::new(
"CanMintAssetsWithDefinition".parse().unwrap(),
&json!({ "asset_definition_id": asset_definition_id }),
);

// Create a new `CanRemoveKeyValueInAssetDefinition` permission token
// that allows to remove key value from `alice_xor_id` asset definition
let permission_to_remove_key_value_from_xor: PermissionToken =
key_value::CanRemoveKeyValueInAssetDefinition::new(alice_xor_id).into();

// Create an instruction that grants Bob permission
// to remove key value from `alice_xor_id` asset definition
let grant = Instruction::Grant(GrantBox::new(
permission_to_remove_key_value_from_xor,
IdBox::AccountId(bob_id),
));
```

### `CanRegisterDomains`

With `CanRegisterDomains` permission token, a user can
[register](/guide/blockchain/instructions.md#un-register) domains.

```rust
let alice_id = AccountId::from_str("alice@test0")?;
let mut alice = Account::new(alice_id, []).build();

// Create a new `CanRegisterDomains` permission token
// that allows registering new domains
let permission_token_to_register_domains: PermissionToken =
register::CanRegisterDomains::new().into();

// Create an instruction that grants Alice permission to register new domains
let grant = Instruction::Grant(GrantBox::new(
permission_token_to_register_domains,
IdBox::AccountId(alice_id),
```
// Create a permission expression (Grant\Revoke)
let permission_expression = GrantExpr::new(can_mint_asset_with_definition_token, recipients_account);
// Submit the transaction with the permission expression
iroha_client.submit_blocking(permission_expression).unwrap();
```
Loading