Keys

[Previous << Capabilities](https://qiita.com/flowcadence/items/b70151356f4e548f2c91)
[Next >> Contracts](https://qiita.com/flowcadence/items/c8661fbf9eae32ce5926)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#cadenceの言語仕様を学ぶ

Accountにはそれぞれkeyが関連付けられています。アカウントにキーが追加されると、そのキーを使用してトランザクションに署名できるようになります。署名された[トランザクション](https://qiita.com/flowcadence/items/0d73ce09c9da04d8b697)はアカウントにアクセスでき、そのアカウント上で[書き込み操作を実行](https://qiita.com/flowcadence/items/5ddbb79fe8438850cf57#performing-write-operations)できます。

アカウントは、`keys`フィールドを通じてキーを公開します。このフィールドの型は`Account.Keys`です。

<h1 id="Account.Keys">Account.Keys</h1>

```ruby
access(all)
struct Keys {

    /* The total number of unrevoked keys in this account. */
    access(all)
    let count: UInt64

    /** Returns the key at the given index, if it exists, or nil otherwise.
      *
      * Revoked keys are always returned, but they have `isRevoked` field set to true.
      */
    access(all)
    view fun get(keyIndex: Int): AccountKey?

    /** Iterate over all unrevoked keys in this account,
      * passing each key in turn to the provided function.
      *
      * Iteration is stopped early if the function returns `false`.
      *
      * The order of iteration is undefined.
      */
    access(all)
    fun forEach(_ function: fun(AccountKey): Bool)

    /** Adds a new key with the given hashing algorithm and a weight.
      *
      * Returns the added key.
      */
    access(Keys | AddKey)
    fun add(
        publicKey: PublicKey,
        hashAlgorithm: HashAlgorithm,
        weight: UFix64
    ): AccountKey

    /** Marks the key at the given index revoked, but does not delete it.
      *
      * Returns the revoked key if it exists, or nil otherwise.
      */
    access(Keys | RevokeKey)
    fun revoke(keyIndex: Int): AccountKey?
}

entitlement Keys

entitlement AddKey
entitlement RevokeKey
```

<h1 id="Account-key">Account key</h1>

アカウントキーの構造は次のようになります。
```ruby
access(all)
struct AccountKey {

	const accountKeyHashAlgorithmFieldDocString = ``
	const accountKeyWeightFieldDocString = ``
	const accountKeyIsRevokedFieldDocString = ``

	/* The index of the account key. */
    access(all)
    let keyIndex: Int

    /* The public key of the account key. */
    let publicKey: PublicKey

    /* The hash algorithm used by the public key. */
    let hashAlgorithm: HashAlgorithm

    /* The weight assigned to the account key,
       with a maximum of 1000.0 */
    let weight: UFix64

    /* The flag indicating whether the key is revoked. */
    let isRevoked: Bool
}
```
有効なアカウントキーの`publicKey`フィールドは、`ECDSA_P256`または`ECDSA_secp256k1`署名アルゴリズムの`PublicKey`です。Cadenceがサポートするその他の署名アルゴリズムの公開鍵は、有効なアカウント公開鍵ではありません。

公開鍵の作成および有効性に関する詳細は、[public keysセクション](https://qiita.com/flowcadence/items/1bdc645b097a5efbb9cf#public-keys)を参照してください。

有効なアカウント鍵の`hashAlgorithm`フィールドは、`SHA2_256`または`SHA3_256`のいずれかです。

Cadenceがサポートするその他のすべてのハッシュアルゴリズムは、アカウント鍵でのハッシュ処理には有効ではありません。

ハッシュアルゴリズムの詳細については、[hash algorithmsセクション](https://qiita.com/flowcadence/items/1bdc645b097a5efbb9cf#hash-algorithms)を参照してください。
<h1 id="Getting-an-account-key">Getting an account key</h1>

`keys.get` および `keys.forEach` 関数を使用すると、アカウントのキーを取得できます。

`get`関数を使用すると、特定のインデックスに一致するキーを取得できます。この関数は、キーが存在する場合はそのキーを返し、存在しない場合は`nil`を返します。
```ruby
access(all)
view fun get(keyIndex: Int): AccountKey?
```
`forEach` 関数を使用すると、アカウントのすべてのキーを繰り返し取得し何らかの処理をすることができます。
```ruby
access(all)
fun forEach(_ function: fun(AccountKey): Bool)
```
Accountの各keyについて、`forEach`関数は指定されたコールバック関数を呼び出し、そのキーを渡します。コールバック関数が`true`を返すと繰り返し処理が継続され、`false`を返すと繰り返し処理が停止します。

:::note warn
⚠ WARNING
`keys.get` および `keys.forEach` 関数には、無効化されたキーが含まれます。無効化されたキーは、`isRevoked`フィールドが`true`に設定されています。
:::
```ruby
access(all)
fun main() {
    let account = getAccount(0x42)

    /* Get the third key from the account. */
    let thirdKey = account.keys.get(keyIndex: 2)
    // ...

    /* Iterate over all keys of the account. */
    account.keys.forEach(fun (key: AccountKey): Bool {
        // ...
        return true
    })
}
```
<h1 id="Adding-an-account-key">Adding an account key</h1>

`keys.add`関数は、Accountにアクセスするためのkeyを作成します。

```ruby
access(Keys | AddKey)
fun add(
    publicKey: PublicKey,
    hashAlgorithm: HashAlgorithm,
    weight: UFix64
): AccountKey
```

`add`関数を呼び出すには、粗粒度の`Keys`権限（`auth(Keys) &Account`）または、細粒度の`AddKey`権限（`auth(AddKey) &Account`）で認証された参照経由でアカウントにアクセスする必要があります。

例えば、トランザクションに署名した既存のアカウントに公開鍵を追加するには、以下のようにします。
```ruby
transaction(publicKey: [UInt8]) {
    prepare(signer: auth(AddKey) &Account) {
        let key = PublicKey(
            publicKey: publicKey,
            signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
        )

        signer.keys.add(
            publicKey: key,
            hashAlgorithm: HashAlgorithm.SHA3_256,
            weight: 10.0
        )
    }
}
```

アカウントを作成する、より複雑なトランザクションでは、トランザクションの署名者がアカウント作成の費用を支払い、1つのkeyにアカウントへのアクセス権限を与えます。以下のような形になります。
```ruby
transaction(publicKey: [UInt8]) {
    prepare(signer: auth(BorrowValue) &Account) {
        let key = PublicKey(
            publicKey: publicKey,
            signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
        )

        let account = Account(payer: signer)

        account.keys.add(
            publicKey: key,
            hashAlgorithm: HashAlgorithm.SHA3_256,
            weight: 10.0
        )
    }
}
```
<h1 id="Revoking-an-account-key">Revoking an account key</h1>

`revoke`関数は、Accountへのアクセス権をキーから取り消します。この関数は、指定されたインデックスのキーを取り消した(revoked)とマークするだけで、決して削除はしません。

```ruby
access(Keys | RevokeKey)
fun revoke(keyIndex: Int): AccountKey?
```
`revoke`関数を呼び出すには、粗粒度の`Keys`権限（`auth(Keys) &Account`）または、細粒度の`RevokeKey`権限（`auth(RevokeKey) &Account`）で認証された参照によるアカウントへのアクセスが必要です。

例えば、トランザクションに署名したアカウントの3番目のキーを取り消すには：
```ruby
transaction {
    prepare(signer: auth(RevokeKey) &Account) {
        let revokedKey = signer.keys.revoke(keyIndex: 2)
        // ...
    }
}
```


翻訳元

https://cadence-lang.org/docs/language/accounts/keys

***
<b>[Previous << Capabilities](https://qiita.com/flowcadence/items/b70151356f4e548f2c91)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Keys)

<b>[Next >> Contracts](https://qiita.com/flowcadence/items/c8661fbf9eae32ce5926)</b>