A JSON format for the storage and retrieval of Ethereum 2 hierarchical deterministic (HD) wallet definitions.
Ethereum has the concept of keystores: pieces of data that define a key (see EIP-2335 for details). This adds the concept of walletstores: stores that define wallets and how keys in said wallets are created.
Hierarchical deterministic wallets create keys from a seed and a path. The seed needs to be accessible to create new keys, however it should also be protected to the same extent as private keys to stop it from becoming an easy attack vector. The path, or at least the variable part of it, needs to be stored to ensure that keys are not duplicated. Providing a standard method to do this can promote interoperability between wallets and similar software.
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 hierarchical deterministic 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 the string hierarchical deterministic
.
The crypto
provided is the secure storage of a secret for wallets that require this information. For hierarchical deterministic wallets this is the seed from which they calculate individual private keys.
This element MUST be present. It MUST be an object that follows the definition described in EIP-2335.
The nextaccount
provided is the index to be supplied to the path m/12381/60/<index>/0
when creating a new private key from the seed. The path follows EIP-2334.
This element MUST be present if the wallet type requires it. It MUST be a non-negative integer.
The walletstore follows a similar format to that of the keystore described in EIP-2335.
{
"$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"
"crypto"
"nextaccount"
],
"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.
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 hierarchical deterministic wallet can be found at https://github.com/wealdtech/go-eth2-wallet-hd.
The seed stored in the crypto
section of the wallet can be used to generate any key along the derived path. As such, the security of all keys generated by HD wallets is reduced to the security of the passphrase and strength of the encryption used to protect the seed, regardless of the security of the passphrase and strength of the encryption used to protect individual keystores.
It is possible to work with only the walletstore plus an index for each key, in which case stronger passphrases can be used as decryption only needs to take place once. It is also possible to use generated keystores without the walletstore, in which case a breach of security will expose only the keystore.
An example high-security configuration may involve the walletstore existing on an offline computer, from which keystores are generated. The keystores can then be moved individually to an online computer to be used for signing.
Copyright and related rights waived via CC0.