Skip to main content
Version: Next

Keys

Accounts have keys associated with them. When a key is added to an account, the key can be used to sign a transaction, which in turn gets access the account and can perform write operations on it.

An account exposes its keys through the keys field, which has the type Account.Keys.

Account.Keys


_43
access(all)
_43
struct Keys {
_43
_43
/// The total number of unrevoked keys in this account.
_43
access(all)
_43
let count: UInt64
_43
_43
/// Returns the key at the given index, if it exists, or nil otherwise.
_43
///
_43
/// Revoked keys are always returned, but they have `isRevoked` field set to true.
_43
access(all)
_43
view fun get(keyIndex: Int): AccountKey?
_43
_43
/// Iterate over all unrevoked keys in this account,
_43
/// passing each key in turn to the provided function.
_43
///
_43
/// Iteration is stopped early if the function returns `false`.
_43
///
_43
/// The order of iteration is undefined.
_43
access(all)
_43
fun forEach(_ function: fun(AccountKey): Bool)
_43
_43
/// Adds a new key with the given hashing algorithm and a weight.
_43
///
_43
/// Returns the added key.
_43
access(Keys | AddKey)
_43
fun add(
_43
publicKey: PublicKey,
_43
hashAlgorithm: HashAlgorithm,
_43
weight: UFix64
_43
): AccountKey
_43
_43
/// Marks the key at the given index revoked, but does not delete it.
_43
///
_43
/// Returns the revoked key if it exists, or nil otherwise.
_43
access(Keys | RevokeKey)
_43
fun revoke(keyIndex: Int): AccountKey?
_43
}
_43
_43
entitlement Keys
_43
_43
entitlement AddKey
_43
entitlement RevokeKey

Account key

An account key has the following structure:


_24
access(all)
_24
struct AccountKey {
_24
_24
const accountKeyHashAlgorithmFieldDocString = ``
_24
const accountKeyWeightFieldDocString = ``
_24
const accountKeyIsRevokedFieldDocString = ``
_24
_24
/// The index of the account key.
_24
access(all)
_24
let keyIndex: Int
_24
_24
/// The public key of the account key.
_24
let publicKey: PublicKey
_24
_24
/// The hash algorithm used by the public key.
_24
let hashAlgorithm: HashAlgorithm
_24
_24
/// The weight assigned to the account key,
_24
/// with a maximum of 1000.0
_24
let weight: UFix64
_24
_24
/// The flag indicating whether the key is revoked.
_24
let isRevoked: Bool
_24
}

Refer to the public keys section for more details on the creation and validity of public keys.

Refer to the hash algorithms section for more details on supported hash algorithms.

Getting an account key

The functions keys.get and keys.forEach allow retrieving the keys of an account.

The get function allows retrieving a key with a specific index. The function returns the key if it exists, and nil otherwise.


_10
access(all)
_10
view fun get(keyIndex: Int): AccountKey?

The forEach function allows iterating over all keys of an account.


_10
access(all)
_10
fun forEach(_ function: fun(AccountKey): Bool)

For each key of the account, the forEach function calls the given callback, passing the key to it. When the callback function returns true the iteration continues, and when it returns false, iteration stops.

warning

The keys.get and keys.forEach functions include revoked keys, which have the isRevoked field set to true.


_14
access(all)
_14
fun main() {
_14
let account = getAccount(0x42)
_14
_14
// Get the third key from the account.
_14
let thirdKey = account.keys.get(keyIndex: 2)
_14
// ...
_14
_14
// Iterate over all keys of the account.
_14
account.keys.forEach(fun (key: AccountKey): Bool {
_14
// ...
_14
return true
_14
})
_14
}

Adding an account key

The function keys.add allows a key to access an account.


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

Calling the add function requires access to an account via a reference which is authorized with the coarse-grained Keys entitlement (auth(Keys) &Account), or the fine-grained AddKey entitlement (auth(AddKey) &Account).

For example, to add a public key to an existing account, which signed the transaction:


_14
transaction(publicKey: [UInt8]) {
_14
prepare(signer: auth(AddKey) &Account) {
_14
let key = PublicKey(
_14
publicKey: publicKey,
_14
signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
_14
)
_14
_14
signer.keys.add(
_14
publicKey: key,
_14
hashAlgorithm: HashAlgorithm.SHA3_256,
_14
weight: 10.0
_14
)
_14
}
_14
}

A more complex transaction, which creates an account, has the signer of the transaction pay for the account creation, and authorizes one key to access the account, could look like:


_16
transaction(publicKey: [UInt8]) {
_16
prepare(signer: auth(BorrowValue) &Account) {
_16
let key = PublicKey(
_16
publicKey: publicKey,
_16
signatureAlgorithm: SignatureAlgorithm.ECDSA_P256
_16
)
_16
_16
let account = Account(payer: signer)
_16
_16
account.keys.add(
_16
publicKey: key,
_16
hashAlgorithm: HashAlgorithm.SHA3_256,
_16
weight: 10.0
_16
)
_16
}
_16
}

Revoking an account key

The revoke function revokes a key from accessing an account. The function only marks the key at the given index as revoked, but never deletes it.


_10
access(Keys | RevokeKey)
_10
fun revoke(keyIndex: Int): AccountKey?

Calling the revoke function requires access to an account via a reference which is authorized with the coarse-grained Keys entitlement (auth(Keys) &Account), or the fine-grained RevokeKey entitlement (auth(RevokeKey) &Account).

For example, to revoke the third key of the account which signed the transaction:


_10
transaction {
_10
prepare(signer: auth(RevokeKey) &Account) {
_10
let revokedKey = signer.keys.revoke(keyIndex: 2)
_10
// ...
_10
}
_10
}