Previous << Storage
Next >> Keys
アカウントには、それと関連付けられたCapabilityがあります。
アカウントは、capabilities
フィールドを通じてそのCapabilityを公開しています。このフィールドの型は、Account.Capabilities
です。
Account.Capabilities
access(all)
struct Capabilities {
/* The storage capabilities of the account. */
access(mapping CapabilitiesMapping)
let storage: Account.StorageCapabilities
/* The account capabilities of the account. */
access(mapping CapabilitiesMapping)
let account: Account.AccountCapabilities
/** Returns the capability at the given public path.
* If the capability does not exist,
* or if the given type is not a supertype of the capability's borrow type,
* returns an "invalid" capability with ID 0 that will always fail to `check` or `borrow` */
access(all)
view fun get<T: &Any>(_ path: PublicPath): Capability<T>
/** Borrows the capability at the given public path.
* Returns nil if the capability does not exist, or cannot be borrowed using the given type.
* The function is equivalent to `get(path).borrow()`. */
access(all)
view fun borrow<T: &Any>(_ path: PublicPath): T?
/* Returns true if a capability exists at the given public path. */
access(all)
view fun exists(_ path: PublicPath): Bool
/** Publish the capability at the given public path.
*
* If there is already a capability published under the given path, the program aborts.
*
* The path must be a public path, i.e., only the domain `public` is allowed. */
access(Capabilities | PublishCapability)
fun publish(_ capability: Capability, at: PublicPath)
/** Unpublish the capability published at the given path.
*
* Returns the capability if one was published at the path.
* Returns nil if no capability was published at the path. */
access(Capabilities | UnpublishCapability)
fun unpublish(_ path: PublicPath): Capability?
}
entitlement Capabilities
entitlement PublishCapability
entitlement UnpublishCapability
Checking the existence of public capabilities
capabilities.check
関数は、指定されたパスで以前にpublic Capabilityがpublish(保存)されていたかどうかを判断します。
access(all)
view fun exists(_ path: PublicPath): Bool
アカウントが指定されたパスでCapabilityを持っている場合、関数は true を返し、そうでない場合は false を返します。
Getting public capabilities
capabilities.get
関数は、publish(保存)されているpublic Capabilityを取得します。
access(all)
view fun get<T: &Any>(_ path: PublicPath): Capability<T>
アカウントが指定されたパス且つ指定されたタイプのCapabilityを持っている場合、関数はそれを返します。
アカウントが指定されたパスで保存しているCapabilityがない場合、または指定されたタイプがCapabilityのborrow typeのスーパータイプでない場合、関数はIDが0の「無効」なCapabilityを返します。このCapabilityは、check
またはborrow
を行うときに常に失敗します。
便利関数capabilities.borrow
は、以前にpublish(保存)されたpublic Capabilityを1アクションで取得および借用します。
access(all)
view fun borrow<T: &Any>(_ path: PublicPath): T?
アカウントが指定されたパス且つ指定されたタイプのCapabilityを保存している場合、関数はそのCapabilityを借用し、その結果の参照(reference)をオプショナルとして返します。
アカウントが指定されたパスでCapabilityを保存していない場合、もしくは、型パラメータT
で要求されたタイプが保存されたCapabilityのものと一致しない場合、関数はnil
を返します。
Managing capabilities
Capabilityには、ストレージCapabilityとアカウントCapabilityの2種類があります。
-
ストレージCapabilityは、パスを介して、アカウントストレージ内のオブジェクトへのアクセスを許可します。アカウントは、
capabilities.storage
フィールド(タイプはAccount.StorageCapabilities
になります)によって、ストレージCapabilityの管理が可能です。 -
アカウントCapabilityは、Accountへのアクセスを許可します。アカウントは、
capabilities.account
フィールド(タイプはAccount.AccountCapabilities
になります)によって、アカウントCapabilityの管理が可能です。
Capabilityおよびそのすべてのコピーは、Capability controllerによって管理されます。
-
ストレージCapabilityはストレージCapabilityコントローラによって制御されます(原文: are controlled)。ストレージCapabilityコントローラの型は
StorageCapabilityController
です。 -
アカウントCapabilityはアカウントCapabilityコントローラによって制御されます。アカウントCapabilityコントローラの型は
AccountCapabilityController
です。
Account.StorageCapabilities and Account.AccountCapabilities
access(all)
struct StorageCapabilities {
/* Issue|create a new storage capability. */
access(Capabilities | StorageCapabilities | IssueStorageCapabilityController)
fun issue<T: &Any>(_ path: StoragePath): Capability<T>
/* Issue|create a new storage capability. */
access(Capabilities | StorageCapabilities | IssueStorageCapabilityController)
fun issueWithType(_ path: StoragePath, type: Type): Capability
/** Get the storage capability controller for the capability with the specified ID.
*
* Returns nil if the ID does not reference an existing storage capability.
*/
access(Capabilities | StorageCapabilities | GetStorageCapabilityController)
view fun getController(byCapabilityID: UInt64): &StorageCapabilityController?
/* Get all storage capability controllers for capabilities that target this storage path */
access(Capabilities | StorageCapabilities | GetStorageCapabilityController)
view fun getControllers(forPath: StoragePath): [&StorageCapabilityController]
/** Iterate over all storage capability controllers for capabilities that target this storage path,
* passing a reference to each controller to the provided callback function.
*
* Iteration is stopped early if the callback function returns `false`.
*
* If a new storage capability controller is issued for the path,
* an existing storage capability controller for the path is deleted,
* or a storage capability controller is retargeted from or to the path,
* then the callback must stop iteration by returning false.
* Otherwise, iteration aborts.
*/
access(Capabilities | StorageCapabilities | GetStorageCapabilityController)
fun forEachController(
forPath: StoragePath,
_ function: fun(&StorageCapabilityController): Bool
)
}
access(all)
struct AccountCapabilities {
/* Issue/create a new account capability. */
access(Capabilities | AccountCapabilities | IssueAccountCapabilityController)
fun issue<T: &Account>(): Capability<T>
/* Issue/create a new account capability. */
access(Capabilities | AccountCapabilities | IssueAccountCapabilityController)
fun issueWithType(_ type: Type): Capability
/** Get capability controller for capability with the specified ID.
*
* Returns nil if the ID does not reference an existing account capability.
*/
access(Capabilities | AccountCapabilities | GetAccountCapabilityController)
view fun getController(byCapabilityID: UInt64): &AccountCapabilityController?
/* Get all capability controllers for all account capabilities. */
access(Capabilities | AccountCapabilities | GetAccountCapabilityController)
view fun getControllers(): [&AccountCapabilityController]
/** Iterate over all account capability controllers for all account capabilities,
* passing a reference to each controller to the provided callback function.
*
* Iteration is stopped early if the callback function returns `false`.
*
* If a new account capability controller is issued for the account,
* or an existing account capability controller for the account is deleted,
* then the callback must stop iteration by returning false.
* Otherwise, iteration aborts.
*/
access(Capabilities | AccountCapabilities | GetAccountCapabilityController)
fun forEachController(_ function: fun(&AccountCapabilityController): Bool)
}
entitlement StorageCapabilities
entitlement AccountCapabilities
entitlement GetStorageCapabilityController
entitlement IssueStorageCapabilityController
entitlement GetAccountCapabilityController
entitlement IssueAccountCapabilityController
entitlement mapping CapabilitiesMapping {
include Identity
StorageCapabilities -> GetStorageCapabilityController
StorageCapabilities -> IssueStorageCapabilityController
AccountCapabilities -> GetAccountCapabilityController
AccountCapabilities -> IssueAccountCapabilityController
}
AccountCapabilityController and StorageCapabilityController
access(all)
struct AccountCapabilityController {
/* The capability that is controlled by this controller. */
access(all)
let capability: Capability
/** An arbitrary "tag" for the controller.
* For example, it could be used to describe the purpose of the capability.
* Empty by default.
*/
access(all)
var tag: String
/* Updates this controller's tag to the provided string */
access(all)
fun setTag(_ tag: String)
/* The type of the controlled capability, i.e. the T in `Capability<T>`. */
access(all)
let borrowType: Type
/* The identifier of the controlled capability.
All copies of a capability have the same ID. */
access(all)
let capabilityID: UInt64
/** Delete this capability controller,
* and disable the controlled capability and its copies.
*
* The controller will be deleted from storage,
* but the controlled capability and its copies remain.
*
* Once this function returns, the controller is no longer usable,
* all further operations on the controller will panic.
*
* Borrowing from the controlled capability or its copies will return nil.
*/
access(all)
fun delete()
}
access(all)
struct StorageCapabilityController {
/* The capability that is controlled by this controller. */
access(all)
let capability: Capability
/** An arbitrary "tag" for the controller.
* For example, it could be used to describe the purpose of the capability.
* Empty by default.
*/
access(all)
var tag: String
/* Updates this controller's tag to the provided string */
access(all)
fun setTag(_ tag: String)
/* The type of the controlled capability, i.e. the T in `Capability<T>`. */
access(all)
let borrowType: Type
/* The identifier of the controlled capability.
All copies of a capability have the same ID. */
access(all)
let capabilityID: UInt64
/** Delete this capability controller,
* and disable the controlled capability and its copies.
*
* The controller will be deleted from storage,
* but the controlled capability and its copies remain.
*
* Once this function returns, the controller is no longer usable,
* all further operations on the controller will panic.
*
* Borrowing from the controlled capability or its copies will return nil.
*/
access(all)
fun delete()
/* Returns the targeted storage path of the controlled capability. */
access(all)
fun target(): StoragePath
/* Retarget the controlled capability to the given storage path.
The path may be different or the same as the current path. */
access(all)
fun retarget(_ target: StoragePath)
}
Issuing capabilities
Capabilityは、対象アカウントの中に発行することで作成されます。
ストレージCapabilityの発行
capabilities.storage.issue
関数は、指定したストレージpathを対象とし、指定したタイプで借用できる新しいストレージCapabilityを発行します。
access(Capabilities | StorageCapabilities | IssueStorageCapabilityController)
fun issue<T: &Any>(_ path: StoragePath): Capability<T>
issue
関数を呼び出すには、粗粒度のCapabilities
権限またはStorageCapabilities
権限(auth(Capabilities) &Account
またはauth(StorageCapabilities) &Account
)または、細粒度のIssueStorageCapabilityController
権限(auth(IssueStorageCapabilityController) &Account
)で認証された参照経由でアカウントにアクセスする必要があります。
pathはストレージパスでなければならず、domain storage
を持っていなければなりません。
例えば、以下のトランザクションは、必要なWithdraw
権限(Entitlement)で借用されるCapabilityを認証することで、保存されたvaultから引き出す(withdraw)権限を付与する新しいストレージCapabilityを発行します。(補足: 要はリソース(資産)を引き出す権限のあるCapabilityを作るということ)
transaction {
prepare(signer: auth(IssueStorageCapabilityController) &Account) {
let capability = signer.capabilities.storage.issue<auth(Withdraw) &Vault>(/storage/vault)
/* ... */
}
}
アカウントCapabilityの発行
capabilities.account.issue
関数は、アカウントを対象にした、指定したタイプで借用できる、新しいアカウントCapabilityを発行します。
access(Capabilities | AccountCapabilities | IssueAccountCapabilityController)
fun issue<T: &Account>(): Capability<T>
issue
関数を呼び出すには、粗粒度のCapabilities
権限またはAccountCapabilities
権限(auth(Capabilities) &Account
またはauth(AccountCapabilities) &Account
)または、細粒度のIssueAccountCapabilityController
権限(auth(IssueAccountCapabilityController) &Account
)で認証された参照経由でアカウントにアクセスする必要があります。
例えば、次のトランザクションは、必要なSaveValue
Entitlementで借用されるCapabilityを認証することで、アカウントにオブジェクトを保存する能力を付与する(原文: grants the ability to save)、新しいアカウントCapabilityを発行します。
transaction {
prepare(signer: auth(IssueAccountCapabilityController) &Account) {
let capability = signer.capabilities.account.issue<auth(SaveValue) &Account>()
/* ... */
}
}
Publishing capabilities
Capabilityは、それをpublishすることで一般に公開することができます。
capabilities.publish
関数は、指定されたpublic pathでCapabilityをpublishします。
access(Capabilities | PublishCapability)
fun publish(_ capability: Capability, at: PublicPath)
publish
関数を呼び出すには、粗粒度のCapabilities
権限(auth(Capabilities) &Account
)または、細粒度のPublishCapability
権限(auth(PublishCapability) &Account
)で認証された参照を介してアカウントにアクセスする必要があります
例えば、以下のトランザクションでは、新しいストレージCapabilityを発行し、パス/public/vault
の下でそれをpublishします。これにより、誰でもそのCapabilityにアクセスしてborrowし、格納されたvaultにアクセスできるようになります。Note: 参照(reference)タイプは認証されていないため、Capabilityがborrowされた場合、公開されている(access(all)
)フィールドとオブジェクトの関数のみにアクセスできます。(補足: 本人以外書き換え権限はありません)
transaction {
prepare(signer: auth(Capabilities) &Account) {
let capability = signer.capabilities.storage.issue<&Vault>(/storage/vault)
signer.capabilities.publish(capability, at: /public/vault)
}
}
Unpublishing capabilities
capabilities.unpublish
関数は、指定されたpublic pathからCapabilityを解除(unpublish)します。
access(Capabilities | UnpublishCapability)
fun unpublish(_ path: PublicPath): Capability?
unpublish
関数を呼び出すには、粗粒度のCapabilities
権限(auth(Capabilities) &Account
)で認証された参照経由でアカウントにアクセスするか、または、細粒度のUnpublishCapability
権限(auth(UnpublishCapability) &Account
)で認証された参照経由でアカウントにアクセスする必要があります。
パスで保存されているCapabilityがある場合、そのCapabilityはパスから削除され、返されます。パスで保存されている機能がない場合、この関数はnil
を返します。
例えば、以下のトランザクションは、パス/public/vault
で保存されたCapabilityを解除します。
transaction {
prepare(signer: auth(Capabilities) &Account) {
signer.capabilities.unpublish(/public/vault)
}
}
Tagging capabilities
Capabilityには任意の文字列であるタグを関連付けることができます。タグは、Capabilityの目的を記録するなど、さまざまな目的で使用できます。デフォルトでは空です。タグはCapability controllerに保存されます。
ストレージCapabilityコントローラ(StorageCapabilityController
)とアカウントCapabilityコントローラ(AccountCapabilityController
)の両方に、tag
フィールドとsetTag
関数が用意されており、これを使用してタグを取得したり設定したりすることができます。
access(all)
var tag: String
access(all)
fun setTag(_ tag: String)
Retargeting storage capabilities
ストレージCapability(StorageCapabilityController
)は、発行(保存)後に別のstorage pathに再ターゲットできます。
target
関数は制御されたCapabilityのstorage pathを返し、retarget
関数は新しいstorage pathを設定します。
access(all)
fun target(): StoragePath
access(all)
fun retarget(_ target: StoragePath)
Revoking capabilities
Capabilityおよびそのすべてのコピーは、Capabilityのコントローラーを削除することで取り消すことができます。
delete
関数は、コントローラー(StorageCapabilityController
またはAccountCapabilityController
)を削除します。
access(all)
fun delete()
Getting capability controllers
StorageCapabilities
およびAccountCapabilities
というCapability managementタイプにより、Capabilityのコントローラを取得できるだけでなく、既存のすべてのコントローラを順に取得することもできます。
ストレージCapabilityコントローラの取得
capabilities.storage.getController
関数は、指定されたCapability IDのCapabilityに対応するストレージCapabilityコントローラを取得します。
access(Capabilities | StorageCapabilities | GetStorageCapabilityController)
view fun getController(byCapabilityID: UInt64): &StorageCapabilityController?
getController
関数を呼び出すには、粗粒度のCapabilities
権限またはStorageCapabilities
権限(auth(Capabilities) &Account
またはauth(StorageCapabilities) &Account
)で認証された参照によるアカウントへのアクセス、または、細粒度のGetStorageCapabilityController
権限(auth(GetStorageCapabilityController) &Account
)が必要です。
指定されたIDのCapabilityに対応するストレージCapabilityコントローラが存在する場合は、オプショナルとしてその参照が返されます。指定されたCapability IDに対応するストレージCapabilityコントローラが存在しない場合は、この関数はnil
を返します。
アカウントCapabilityコントローラの取得
capabilities.account.getController
関数は、指定されたCapability IDに対応するアカウントCapabilityコントローラを取得します。
access(Capabilities | AccountCapabilities | GetAccountCapabilityController)
view fun getController(byCapabilityID: UInt64): &AccountCapabilityController?
getController
関数を呼び出すには、粗粒度のCapabilities
権限またはAccountCapabilities
権限(auth(Capabilities) &Account
またはauth(AccountCapabilities) &Account
)で認証された参照によるアカウントへのアクセス、または、細粒度のGetAccountCapabilityController
権限(auth(GetAccountCapabilityController) &Account
)が必要です。
指定したIDのCapabilityに対応するアカウントCapabilityコントローラが存在する場合、この関数はオプショナルとしてその参照を返します。指定したCapability IDに対応するアカウントCapabilityコントローラが存在しない場合、この関数はnil
を返します。
ストレージCapabilityコントローラの反復処理
関数getControllers
およびforEachController
を使用すると、ストレージパスのすべてのストレージCapabilityコントローラを反復処理できます。
access(Capabilities | StorageCapabilities | GetStorageCapabilityController)
view fun getControllers(forPath: StoragePath): [&StorageCapabilityController]
access(Capabilities | StorageCapabilities | GetStorageCapabilityController)
fun forEachController(
forPath: StoragePath,
_ function: fun(&StorageCapabilityController): Bool
)
getControllers
およびforEachController
関数を呼び出すには、粗粒度のCapabilities
権限またはStorageCapabilities
権限(auth(Capabilities) &Account
またはauth(StorageCapabilities) &Account
)で認証された参照によるアカウントへのアクセス、または、細粒度のGetStorageCapabilityController
権限(auth(GetStorageCapabilityController) &Account
)が必要です。
getControllers
関数は、すべてのストレージCapabilityコントローラへの参照の新しい配列を返します。
forEachController
関数は、各ストレージCapabilityコントローラに対して指定のコールバック関数を呼び出し、その関数への参照を渡します。コールバック関数がfalse
を返すと、反復処理が停止します。
アカウントCapabilityコントローラの反復処理
getControllers
関数およびforEachController
関数を使用すると、アカウントのすべてのアカウントCapabilityコントローラを反復処理できます。
access(Capabilities | AccountCapabilities | GetAccountCapabilityController)
view fun getControllers(): [&AccountCapabilityController]
access(Capabilities | AccountCapabilities | GetAccountCapabilityController)
fun forEachController(_ function: fun(&AccountCapabilityController): Bool)
getControllers
関数およびforEachController
関数を呼び出すには、粗粒度のCapabilities
権限またはAccountCapabilities
権限(auth(Capabilities) &Account
またはauth(AccountCapabilities) &Account
)または、細粒度のGetAccountCapabilityController
権限(auth(GetAccountCapabilityController) &Account
)で認証された参照によるアカウントへのアクセスが必要です。
getControllers
関数は、すべてのアカウントCapabilityコントローラへの参照の新しい配列を返します。
forEachController
関数は、各アカウントCapabilityコントローラに対して指定のコールバック関数を呼び出し、その関数への参照を渡します。コールバック関数がfalse
を返すと、繰り返し処理が停止します。
Example
entitlement Increment
/* Declare a resource named `Counter` that has a field `count`
* and a function `increment`, which requires the `Increment` entitlement.
*/
access(all)
resource Counter {
access(all)
var count: UInt
access(all)
init(count: UInt) {
self.count = count
}
access(Increment)
fun increment(by amount: UInt) {
self.count = self.count + amount
}
}
/* In this example an account reference is available through the constant `account`,
* which has the type `auth(Storage, Capabilities) &Account`,
* i.e., the reference is authorized to perform storage and capability operations. */
/* Create a new instance of the resource type `Counter`
* and save it in the storage of the account.
*
* The path `\/storage\/counter` is used to refer to the stored value.
* Its identifier `counter` was chosen freely and could be something else.
*/
account.storage.save(
<-create Counter(count: 42),
to: /storage/counter
)
/* Issue a new storage capability that allows access to the stored counter resource */
let capability = account.capabilities.storage.issue<&Counter>(/storage/counter)
/* Publish the capability under the path `/public/counter`,
* so that anyone can access the counter resource.
*
* Its identifier `counter` was chosen freely and could be something else.
*/
account.capabilities.publish(capability, at: /public/counter)
次に示す例は、異なるコンテクスト(例えば新しい script や transaction)での例であると想像してください。
/* Get a reference to the account that stores the counter */
let account = getAccount(0x1)
/* Borrow the capability for the counter that is made publicly accessible
* through the path `/public/counter`.
*
* The call of `borrow` returns an optional reference `&Counter?`.
* The borrow succeeds, and the result is not `nil`,
* it is a valid reference, because:
*
* 1. The path `\/public\/counter` stores a capability.
*
* 2. The capability allows to be borrowed as `&Counter`,
* as it has the type `Capability<&Counter>`.
*
* 3. The target of the storage capability, the *path* `\/storage\/counter`,
* stores an object and it has a type which is a subtype of the borrowed type
* (type equality is also considered a subtype relationship).
*
* Finally, force-unwrap the optional reference.
* After the call, the declared constant `counterRef` has type `&Counter`.
*/
let counterRef = account.capabilities.borrow<&Counter>(/public/counter)!
/* Read the field `count` of the `Counter`.
* The field can be accessed, because it has the access modifier `access(all)`.
*
* Even though it is a variable field (`var`),
* it cannot be assigned to from outside of the object.
*/
counterRef.count // is `42`
/* Invalid: The `increment` function is not accessible for the reference,
* because the reference has the type `&Counter`,
* which does not authorize the entitlement `Increment`,
* which is required by the `increment` function
* (it has the access modifier ` access(Increment)`).
*/
counterRef.increment(by: 5)
/* Again, attempt to borrow the capability for the counter,
* but use the type `auth(Increment) &Counter` to re-attempt the call to `increment`.
*
* Getting the capability fails, because the capability was issued using the type `&Counter`.
* After the call, `counterRef2` is `nil`.
*/
let counterRef2 = account.capabilities.borrow<auth(Increment) &Counter>(/public/counter)
翻訳元
Flow BlockchainのCadence version1.0ドキュメント (Capabilities)