Accounts

Klaytn Accounts

Overview of Account, State, and Address

An account in Klaytn is a data structure containing information about a person's balance or a smart contract. Klaytn's state is the collection of all its accounts' states - that is, the past and current state of all data stored across Klaytn's accounts. When a transaction is executed on a Klaytn node, the state of Klaytn consequently changes across all its nodes. The state should be the same across all nodes in the Klaytn network if they have processed the same blocks in the same order. State information of each account is associated with a 20-byte address, which is used to identify each account.

Decoupling Key Pairs From Addresses

An account in a typical blockchain platform is associated with a cryptographically processed address of a certain length that usually looks like this: "0x0fe2e20716753082222b52e753854f40afddffd2". This address is strongly coupled with a key pair. If a key pair is chosen, the address is derived from the public key. This has many disadvantages in terms of user experience. Some of them are the following:

  • It is impossible for users to have addresses they want.

  • It is impossible for users to use multiple key pairs to increase security of their accounts.

  • It is impossible for users to change the account's key pair when the private key is accidentally exposed or when users want to update the private key periodically to increase the account's security.

Those are big hurdles that users cannot think of an address as an identifier in the blockchain platform. To clear this hurdle, Klaytn provides a feature that users can choose their addresses and key pairs. With this feature, users can choose addresses that they want and they can use multiple key pairs to increase security. The number of key pairs can be one or more, and the key pairs can have different roles. For details of multiple key pairs or role-based keys, please refer to Multiple Key Pairs & Role-Based Keys.

It is worth noting that Klaytn also supports the old scheme that a key pair and an address are strongly coupled.

Multiple Key Pairs and Role-Based Keys

As described before, when the private key is stolen, exposed, or somehow compromised, there is nothing to do to restore the account’s security: the best option is to generate another key pair to create a new account, and migrate the balance from the old compromised account to the new one. Lack of support for advanced key schemes such as multi-sig or usage-specific key is yet another source of major inconvenience. To address those problems more efficiently, Klaytn accounts provide the following capabilities:

  • Klaytn account allows the key pair associated with the account to be changed.

  • Klaytn account supports multiple key pairs, along with the ability to assign each key with different purpose.

  • Klaytn account maintains compatibility with accounts having a single key that is strongly coupled with the address.

By utilizing Klaytn account’s role-based multi-key support, end-users can better handle real-life security risk situations such as private key mismanagement. For example, when a user realizes that his or her private key has been exposed, the user can simply replace the compromised private key by removing the exposed key pair from his or her account and creating a new key pair to replace them. This could be achieved by using a dedicated key used for updating account information, created in advance and stored separately from the compromised private key.

Human-Readable Address (HRA)

Although the address scheme (e.g., "0x0fe2e20716753082222b52e753854f40afddffd2") has its own strengths in that it efficiently protects the privacy of account holders, it also proposes major problems in terms of end-user experience. First, it is very difficult for a human brain to memorize, or even recognize, such addresses, making them prone to input mistakes and various human errors that often lead to non-trivial financial damages. Second, such scheme takes away from end-users the power to choose one’s own preferred identity handle that’s easier to memorize or use. Combined, these problems are among the toughest usability hurdles that cause BApp user experience for typical end-users (who are more accustomed to the simpler, frictionless user experience offered by legacy mobile apps or services) to be perceived as alien, incomprehensible, and severely inconvenient. To overcome such challenges without undergoing architectural modifications at large-scale and preserving backward compatibility, Klaytn opts to provide a mapping between a 20-byte address to a 20-byte length text string that end-users could assign their own preferred values to. This feature in Klaytn is called human-readable address (HRA). Currently, this feature is under development, and we will provide more information when it is ready.

Klaytn Wallet Key Format

Klaytn wallet key format is provided to easily handle a private key along with the corresponding address. It makes easier for a user to maintain his/her private key with an address. The format is 0x{private key}0x{type}0x{address in hex} in hexadecimal notation, where {type} must be 00. Other values are reserved. An example is shown below:

0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d80x000xa94f5374fce5edbc8e2a8697c15331677e6ebf0b

This format is currently supported in Klaytn Wallet.

Klaytn Account Types

There are two types of accounts in Klaytn: externally owned accounts (EOAs), and smart contract accounts (SCAs).

Externally Owned Accounts (EOAs)

Externally owned accounts have information such as nonce and balance. This type of accounts does not have code or storage. EOAs are controlled by private keys and do not have code associated with them. An EOA can be created using key pairs and subsequently controlled by anyone with the key pairs. The account key is described in the section Account Key.

Attributes

Attribute

Type

Description

type

uint8 (Go)

The type of externally owned accounts. It must be 0x1 for EOAs.

nonce

uint64 (Go)

A sequence number used to determine the order of transactions. The transaction to be processed next has the same nonce with this value.

balance

*big.Int (Go)

The amount of KLAY the account has.

humanReadable

bool (Go)

A boolean value indicating that the account is associated with a human-readable address. Since HRA is under development, this value is false for all accounts.

key

AccountKey

The key associated with this account. This field can be any of AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, AccountKeyWeightedMultisig, AccountKeyRoleBased. Signatures in transactions are verified with this key.

Smart Contract Accounts (SCAs)

In contrast to EOAs, SCAs have code associated with them and are controlled by their code. SCAs are created by smart contract deployment transactions; once deployed, an SCA cannot initiate new transactions by itself and must be triggered by another account, either by an EOA or another SCA.

Attributes

Attribute

Type

Description

type

uint8 (Go)

The type of smart contract accounts. It must be 0x2 for SCAs.

nonce

uint64 (Go)

A sequence number used to determine the order of transactions. The transaction to be processed next has the same nonce with this value.

balance

*big.Int (Go)

The amount of KLAY the account has.

humanReadable

bool (Go)

A boolean value indicating that the account is associated with a human-readable address. Since HRA is under development, this value is false for all accounts.

key

AccountKey

The key associated with this account. This field can be any of AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, AccountKeyWeightedMultisig, AccountKeyRoleBased. Signatures in transactions are verified with this key.

codeHash

[]byte (Go)

The hash of the account's smart contract code. This value is immutable, which means it is set only when the smart contract is created.

storageRoot

[32]byte (Go)

A 256-bit hash of the root of the Merkle Patricia Trie that contains the values of all the storage variables in the account.

codeFormat

uint8 (Go)

A format of the code in this account. Currently, it supports EVM(0x00) only.

Klaytn Account Type ID

Below are the Account Type ID assigned to each Account Type.

Account Type

Account Type ID

Externally Owned Account (EOA)

0x1

Smart Contract Account (SCA)

0x2

Account Key

An account key represents the key structure associated with an account.

AccountKeyNil

AccountKeyNil represents an empty key. If an account tries to have an AccountKeyNil object, the transaction will be failed. AccountKeyNil is used only for TxTypeAccountUpdate transactions with role-based keys. For example, if an account tries to update RoleAccountUpdate key only, the key field of the TxTypeAccountUpdate transaction would be:

[AccountKeyNil, NewKey, AccountKeyNil]

Then, only the RoleAccountUpdate key is updated. Other roles are not updated. Refer to the AccountKeyRoleBased for more detail.

Attributes

No attributes for AccountKeyNil.

RLP Encoding

0x80

AccountKeyLegacy

AccountKeyLegacy is used for the account having an address derived from the corresponding key pair. If an account has AccountKeyLegacy, the transaction validation process is done like below (as typical Blockchain platforms did):

  • Get the public key from ecrecover(txhash, txsig).

  • Get the address of the public key.

  • The address is the sender.

Attributes

Attribute

Type

Description

Type

uint8 (Go)

The type of AccountKeyLegacy. This must be 0x01.

RLP Encoding

0x01c0

AccountKeyPublic

AccountKeyPublic is used for accounts having one public key. If an account has an AccountKeyPublic object, the transaction validation process is done like below:

  • Get the public key derived from ecrecover(txhash, txsig).

  • Check that the derived public key is the same as the corresponding

    account's public key.

Attributes

Attribute

Type

Description

Type

uint8 (Go)

The type of AccountKeyPublic. This must be 0x02.

Key

[33]byte (Go)

Key should be a compressed public key on S256 curve.

RLP Encoding

0x02 + encode(CompressedPubKey)

NOTE: CompressedPubKey is a public key in a compressed format defined in SEC1. In short, 0x02{PubkeyX} if PubkeyY is an even number or 0x03{PubkeyX} otherwise.

RLP Encoding (Example)

prvkey 0xf8cc7c3813ad23817466b1802ee805ee417001fcce9376ab8728c92dd8ea0a6b
pubkeyX 0xdbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8
pubkeyY 0x906d7170ba349c86879fb8006134cbf57bda9db9214a90b607b6b4ab57fc026e
RLP: 0x02a102dbac81e8486d68eac4e6ef9db617f7fbd79a04a3b323c982a09cdfc61f0ae0e8

AccountKeyFail

If an account has the key AccountKeyFail, the transaction validation process always fails. It can be used for smart contract accounts so that a transaction sent from the smart contract account always fails.

Attributes

Attribute

Type

Description

Type

uint8 (Go)

The type of AcccountKeyFail. It must be 0x03.

RLP Encoding

0x03c0

AccountKeyWeightedMultiSig

AccountKeyWeightedMultiSig is an account key type containing a threshold and WeightedPublicKeys which contains a list whose item is composed of a public key and its weight. To be a valid transaction for an account associated with AccountKeyWeightedMultiSig, the weighted sum of signed public keys should be larger than the threshold.

Attributes

Attribute

Type

Description

Type

uint8 (Go)

The type of AccountKeyWeightedMultiSig. This must be 0x04.

Threshold

uint (Go)

Validation threshold. To be a valid transaction, the weight sum of signatures should be larger than or equal to the threshold.

WeightedPublicKeys

[]{uint, [33]byte} (Go)

A list of weighted public keys. A weighted public key contains a compressed public key and its weight.

RLP Encoding

0x04 + encode([threshold, [[weight, CompressedPubKey1], [weight2, CompressedPubKey2]]])

RLP Encoding (Example)

Threshold 3
Key0 Weight: 1
PubkeyX 0xc734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110e
PubkeyY 0x61a443ac3ffff164d1fb3617875f07641014cf17af6b7dc38e429fe838763712
Key1 Weight: 1
PubkeyX 0x12d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfb
PubkeyY 0x8ef355a8d524eb444eba507f236309ce08370debaa136cb91b2f445774bff842
Key2 Weight: 1
PubkeyX 0xea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cd
PubkeyY 0xb95ebb02d9397b4a8faceb58d485d612f0379a923ec0ddcf083378460a56acca
Key3 Weight: 1
PubkeyX 0x8551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6
PubkeyY 0x4206aa84bc8955fcbfcc396854228aa63ebacd81b7311a31ab9d71d90b7ec3d7
RLP: 0x04f89303f890e301a102c734b50ddb229be5e929fc4aa8080ae8240a802d23d3290e5e6156ce029b110ee301a10212d45f1cc56fbd6cd8fc877ab63b5092ac77db907a8a42c41dad3e98d7c64dfbe301a102ea9a9f85065a00d7b9ffd3a8532a574035984587fd08107d8f4cbad6b786b0cde301a1038551bc489d62fa2e6f767ba87fe93a62b679fca8ff3114eb5805e6487b51e8f6

AccountKeyRoleBased

AccountKeyRoleBased represents a role-based key. The roles are specified at Roles.

Attributes

Attribute

Type

Description

Type

uint8 (Go)

The type of AccountKeyRoleBased. It must be 0x05.

Keys

[]{AccountKey} (Go)

A list of keys. A key can be any of AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, and AccountKeyWeightedMultiSig.

Roles

Roles of AccountKeyRoleBased are defined as below:

Role

Description

RoleTransaction

Index 0. Default key. Transactions other than TxTypeAccountUpdate should be signed by the key of this role.

RoleAccountUpdate

Index 1. TxTypeAccountUpdate transaction should be signed by this key. If this key is not present in the account, TxTypeAccountUpdate transaction is validated using RoleTransaction key.

RoleFeePayer

Index 2. If this account wants to send tx fee instead of the sender, the transaction should be signed by this key. If this key is not present in the account, a fee-delegated transaction is validated using RoleTransaction key.

RLP Encoding

0x05 + encode([key1, key2, key3])

Note that key1, key2, and key3 can be any of above keys (AccountKeyNil, AccountKeyLegacy, AccountKeyPublic, AccountKeyFail, and AccountKeyWeightedMultiSig).

Omissible and Extendable Roles

The roles can be omitted from the last, and the omitted roles are mapped to the first role. However, a role in the middle cannot be omitted, which means RoleTransaction and RoleFeePayer cannot be set without RoleAccountUpdate. For example, if a role-based key is set to 0x05 + encode([key1, key2]), RoleFeePayer works as if the key is set like 0x05 + encode([key1, key2, key1]).

This feature is provided to extend more roles in the future. If a new role is provided, the new role of accounts already created with old roles is mapped to the first role.

RLP Encoding (Example)

RoleTransaction Key
PubkeyX 0xe4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d
PubkeyY 0x0a5735a23ce1654b14680054a993441eae7c261983a56f8e0da61280758b5919
RoleAccountUpdate Key
Threshold: 2
Key0 Weight:1
PubkeyX 0xe4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512d
PubkeyY 0x0a5735a23ce1654b14680054a993441eae7c261983a56f8e0da61280758b5919
Key1 Weight:1
PubkeyX 0x36f6355f5b532c3c1606f18fa2be7a16ae200c5159c8031dd25bfa389a4c9c06
PubkeyY 0x6fdf9fc87a16ac359e66d9761445d5ccbb417fb7757a3f5209d713824596a50d
RoleFeePayer Key
PubkeyX 0xc8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447
PubkeyY 0x94c27901465af0a703859ab47f8ae17e54aaba453b7cde5a6a9e4a32d45d72b2
RLP: 0x05f898a302a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512db84e04f84b02f848e301a103e4a01407460c1c03ac0c82fd84f303a699b210c0b054f4aff72ff7dcdf01512de301a10336f6355f5b532c3c1606f18fa2be7a16ae200c5159c8031dd25bfa389a4c9c06a302a102c8785266510368d9372badd4c7f4a94b692e82ba74e0b5e26b34558b0f081447

Account Key Type ID

Below are the Account Key Type ID assigned to each Account Key Type.

Account Key Type

Account Key Type ID

AccountKeyLegacy

0x01

AccountKeyPublic

0x02

AccountKeyFail

0x03

AccountKeyWeightedMultiSig

0x04

AccountKeyRoleBased

0x05