eip | title | author | discussions-to | status | type | category | created | requires |
---|---|---|---|---|---|---|---|---|
2386 |
Ethereum 2 Walletstore |
Jim McDonald <Jim@mcdee.net> |
Draft |
Standards Track |
ERC |
2019-11-21 |
2333, 2334 |
A JSON format for the storage and retrieval of Ethereum 2 wallet definitions.
Ethereum has the concept of keystores: pieces of data that define a key (see EIP-2333 for details). This adds the concept of walletstores: stores that define wallets and how keys in said wallets can be created.
There are multiple different methods to generate private keys. They may, for example, be generated from random data (i.e. non-deterministically) or from seed data and a deterministic path (i.e. hierarchical deterministic). Historically, individual keys have been generated without reference to each other, however the idea of the wallet being both a grouping of keys and a definition of how future keys will be generated allows a higher degree of flexibility. A single user could have multiple wallets that have different levels of security on them, different key generation methods, etc. If a user has multiple wallets they need identification, both programmatically and in a user-friendly fashion.
Given that a wallet has an amount of data and metadata that is useful when accessing existing keys and creating new keys, standardizing this information and how it is stored allows it to be portable between different wallet providers with minimal effort.
The elements of a walletstore are as follows:
The uuid
provided in the walletstore is a randomly-generated type 4 UUID as specified by RFC 4122. It is intended to be used as a 128-bit proxy for referring to a particular wallet, used to uniquely identify wallets.
This element MUST be present. It MUST be a string following the syntactic structure as laid out in section 3 of RFC 4122.
The name
provided in the walletstore is a UTF-8 string. It is intended to serve as the user-friendly accessor. The only restriction on the name is that it MUST NOT start with the underscore (_
) character.
This element MUST be present. It MUST be a string.
The version
provided is the version of the walletstore.
This element MUST be present. It MUST be the integer 1
.
The type
provided is the type of wallet. This informs mechanisms such as key generation.
This element MUST be present. It MUST be one of the following two strings:
non-deterministic
: defined for wallets that create private keys from random informationhierarchical deterministic
: defined for wallets that create private keys based on the hierarchical deterministic method as outlined in EIP-2334
The crypto
provided is the secure storage of a secret for wallets that require this information. For example hierarchical deterministic
wallets have a seed from which they calculate individual private keys.
The crypto
section follows the definition described in EIP-2333.
This element MAY be present if the wallet type requires it.
The nextaccount
provided is the next account to generate for wallets that require this information. For example, hierarchical deterministic
wallets create private keys based on a path that has an incrementing value (the first wallet will be m/12381/60/0/0
, the second m/12381/60/1/0
, the third m/12381/60/2/0
etc.).
This element MAY be present if the wallet type requires it. If present it MUST be a non-negative integer.
The walletstore follows a similar format to that of the keystore described in EIP-2333.
{
"$ref": "#/definitions/Walletstore",
"definitions": {
"Walletstore": {
"type": "object",
"properties": {
"crypto": {
"type": "object",
"properties": {
"kdf": {
"$ref": "#/definitions/Module"
},
"checksum": {
"$ref": "#/definitions/Module"
},
"cipher": {
"$ref": "#/definitions/Module"
}
}
},
"name": {
"type": "string"
},
"nextaccount": {
"type": "integer"
},
"type": {
"type": "string"
},
"uuid": {
"type": "string",
"format": "uuid"
},
"version": {
"type": "integer"
}
},
"required": [
"name",
"type",
"uuid",
"version"
],
"title": "Walletstore"
},
"Module": {
"type": "object",
"properties": {
"function": {
"type": "string"
},
"params": {
"type": "object"
},
"message": {
"type": "string"
}
},
"required": [
"function",
"message",
"params"
]
}
}
}
A standard for walletstores, similar to that for keystores, provides a higher level of compatibility between wallets and allows for simpler wallet and key interchange between them.
{
"name": "Test wallet 1",
"type": "non-deterministic",
"uuid": "5d71e10b-6e00-4cab-a5a0-866a5d8843c3",
"version": 1
}
Password 'testpassword'
Seed 0x147addc7ec981eb2715a22603813271cce540e0b7f577126011eb06249d9227c
{
"crypto": {
"checksum": {
"function": "sha256",
"message": "8bdadea203eeaf8f23c96137af176ded4b098773410634727bd81c4e8f7f1021",
"params": {}
},
"cipher": {
"function": "aes-128-ctr",
"message": "7f8211b88dfb8694bac7de3fa32f5f84d0a30f15563358133cda3b287e0f3f4a",
"params": {
"iv": "9476702ab99beff3e8012eff49ffb60d"
}
},
"kdf": {
"function": "pbkdf2",
"message": "",
"params": {
"c": 16,
"dklen": 32,
"prf": "hmac-sha256",
"salt": "dd35b0c08ebb672fe18832120a55cb8098f428306bf5820f5486b514f61eb712"
}
}
},
"name": "Test wallet 2",
"nextaccount": 0,
"type": "hierarchical deterministic",
"uuid": "b74559b8-ed56-4841-b25c-dba1b7c9d9d5",
"version": 1
}
A Go implementation of the non-deterministic wallet can be found at https://github.com/wealdtech/go-eth2-wallet-nd.
A Go implementation of the hierarchical deterministic wallet can be found at https://github.com/wealdtech/go-eth2-wallet-hd.
Copyright and related rights waived via CC0.