Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ethereum 2 walletstore #2386

Merged
merged 14 commits into from
Sep 11, 2020
208 changes: 208 additions & 0 deletions EIPS/eip-2386.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
---
eip: 2386
title: Ethereum 2 Walletstore
author: Jim McDonald (Jim@mcdee.net)
axic marked this conversation as resolved.
Show resolved Hide resolved
discussions-to: https://ethereum-magicians.org/t/eip-2386-walletstore/3792
status: Draft
type: Standards Track
category: ERC
created: 2019-11-21
requires: 2333, 2334
---

## Simple Summary

A JSON format for the storage and retrieval of Ethereum 2 wallet definitions.

## Abstract

Ethereum has the concept of keystores: pieces of data that define a key (see [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333) for details). This adds the concept of walletstores: stores that define wallets and how keys in said wallets can be created.

## Motivation

Ethereum wallets often require additional metadata above that in the keystore, for example a hierarchical deterministic wallet needs to know the seed and index of the last account created to generate new accounts. In addition, wallets themselves can have names. Standardizing this information and how it is stored allows it to be portable between different wallet providers with minimal effort.

## Specification

The elements of a walletstore are as follows:

### UUID

The `uuid` provided in the walletstore is a randomly-generated type 4 UUID as specified by [RFC 4122](https://tools.ietf.org/html/rfc4122). 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](https://tools.ietf.org/html/rfc4122#section-3).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider **MUST** instead of MUST so they stand out a bit more (this is also the dominant style in this repository).


### Name

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.

### Version

The `version` provided is the version of the walletstore.

This element MUST be present. It MUST be the integer `1`.

### Type

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 information
- `hierarchical deterministic`: defined for wallets that create private keys based on the hierarchical deterministic method as outlined in [EIP-2334](https://eips.ethereum.org/EIPS/eip-2334)

### Crypto

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](https://eips.ethereum.org/EIPS/eip-2333).

This element MAY be present if the wallet type requires it.

### Next Account

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.

## JSON schema
mcdee marked this conversation as resolved.
Show resolved Hide resolved

The walletstore follows a similar format to that of the keystore described in [EIP-2333](https://eips.ethereum.org/EIPS/eip-2333).

```json
{
"$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"
]
}
}
}
```

## Rationale

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels more like motivation than rationale.

Motivation describes why this EIP is generally a good idea.

Rationale describes why specific choices within the EIP were made (e.g., why JSON instead of YML or why constant value 5 instead of 7).


## Test Cases

### Non-deterministic Test Vector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is a key stored in the non-hd case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no key for non-deterministic wallets as the keys are created from random data.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point supporting this if no key is stored? It seems to be a non very useful feature. I may be just confused by the intent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type of the wallet defines if it is deterministic or not. If deterministic it needs a seed/key, if not it doesn't. So the value is required for some wallets and not others. The standard should allow for both options.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any progress on this being merged?

If there is confusion about the purpose it may help to look at https://github.com/wealdtech/go-eth2-wallet#usage regarding the purpose of walletstore. Walletstore is a container that defines how keys are generated within a particular wallet, and provides a container for multiple keys (shown as "account"s) in the diagram at that URL).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am really confused of what use the non-deterministic vector has.

The EIP/ERC should be self contained so that its abstraction and motivation clearly explains everything, without the need for looking for external references.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the motivation section, which should provide more clarity as to their purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the update help clarify the purpose of this EIP? If not, please let me know what is unclear and I will attempt to provider further detail

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please could someone let me know what to do to move this along?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not sure if the non-HD wallet carries it's weight. From what I can tell there's nothing that links the non-HD wallet to generated keys/keystores so it might as well not exist.

Maybe you could help me understand by explaining why anyone would want to export a non-HD wallet from one machine to another?

The non-HD wallet option makes the JSON structure non-trivially more complex; the crypto and path keys might or might-not exist based upon the value of type. Unless I'm missing the purpose of it, it would be a shame to say that one can't be compatible with EIP-2386 unless they implement something that has no practical cryptographic purpose.


```json
{
"name": "Test wallet 1",
"type": "non-deterministic",
"uuid": "5d71e10b-6e00-4cab-a5a0-866a5d8843c3",
"version": 1
}
```

### Hierarchical deterministic Test Vector

Password `'testpassword'`
Seed `0x147addc7ec981eb2715a22603813271cce540e0b7f577126011eb06249d9227c`

```json
{
"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,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we name this as next_account ?

"type": "hierarchical deterministic",
"uuid": "b74559b8-ed56-4841-b25c-dba1b7c9d9d5",
"version": 1
}
```

## Implementation

A Go implementation of the non-deterministic wallet can be found at [https://github.com/wealdtech/go-eth2-wallet-nd](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](https://github.com/wealdtech/go-eth2-wallet-hd).

## Copyright
mcdee marked this conversation as resolved.
Show resolved Hide resolved

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).