ERC-2680 - Ethereum 2 wallet layout

Created 2020-05-29
Status Stagnant
Category ERC
Type Standards Track
Authors

Simple Summary

A standard layout and naming format for walletstore and keystore for both hierarchical (e.g. filesystem, Amazon S3) and non-hierarchical (key/value) storage systems.

Abstract

Ethereum wallets have no standards for their layout in persistent storage, making different wallet implementations incompatible. This defines a standard for the placement of Ethereum walletstores and keystores, making it possible for different software to work with the same wallets and keys.

Motivation

A standard layout for wallets and accounts allows interoperability between validators. This benefits users, as they can move from one validator software to another (and back) without requiring movement of files. This is important because any movement of files containing keys involves danger of either deleting them or duplicating them, both of which could cause loss of access to funds.

Specification

There are four elements for a wallet that need to be addressed. These are defined below.

Base location

The base location is required to be well-known, either pre-defined or defined by the storage system's connection parameters.

For filesystems the pre-defined base location for different operating systems is as follows:

For other hierarchical stores, for example Amazon S3, the base location MUST be the lower-case hex string representing the SHA-256 hash of the string "Ethereum 2 wallet:" appended with the identifier for the hierarchical store. For example, if the account ID for a user's Amazon S3 account is "AbC0438EB" then:

For non-hierarchical stores there is no base location.

Wallet container

The wallet container holds the walletstore and related keystores.

The wallet container is identified by the wallet's UUID. It MUST be a string following the syntactic structure as laid out in section 3 of RFC 4122.

Walletstore

The walletstore element contains the walletstore and is held within the wallet container. It is identified by the wallet's UUID. It MUST be a string following the syntactic structure as laid out in section 3 of RFC 4122.

Keystore

The keystore element contains the keystore for a given key and is held within the wallet container. It is identified by the key's UUID. It MUST be a string following the syntactic structure as laid out in section 3 of RFC 4122.

Hierarchical store example

Hierarchical stores are a common way to store and organize information. The most common example is the filesystem, but a number of object-based stores such as Amazon S3 also provide hierarchical naming.

Putting these elements together for a sample wallet with wallet UUID 1f031fff-c51d-44fc-8baf-d6b304cb70a7 and key UUIDs 1302106c-8441-4e2e-b687-6c77f49fc624 and 4a320100-83fd-4db7-8126-6d6d205ba834 gives the following layout:

- 1f031fff-c51d-44fc-8baf-d6b304cb70a7
+- 1302106c-8441-4e2e-b687-6c77f49fc624
+- 1f031fff-c51d-44fc-8baf-d6b304cb70a7
+- 4a320100-83fd-4db7-8126-6d6d205ba834

Non-hierarchical store example

Non-hierarchical stores use a simplified approach where the wallet UUID and key UUIDs are concatenated using the ':' character. Using the same example wallet and key UUIDs as above would result in objects with the following keys:

1f031fff-c51d-44fc-8baf-d6b304cb70a7:1302106c-8441-4e2e-b687-6c77f49fc624
1f031fff-c51d-44fc-8baf-d6b304cb70a7:1f031fff-c51d-44fc-8baf-d6b304cb70a7
1f031fff-c51d-44fc-8baf-d6b304cb70a7:4a320100-83fd-4db7-8126-6d6d205ba834

Protecting against concurrent write access

TBD

Iterating over wallets

In the case of hierarchical stores and iteration-capable non-hierarchical stores iteration over wallets is a matter of iterating over the files in the root container.

An implementer MAY include an index in the base location. If so then it MUST follow the structure as specified in the following "Index format" section.

Iterating over accounts

In the case of hierarchical stores iteration over accounts is a matter of iterating over the files in the wallet container.

An implementer MAY include an index within a wallet container for accounts within that wallet. If so then it MUST follow the structure as specified in the following "Index format" section.

Index format

The index format is the same for both wallets and accounts, following a standard JSON schema.

{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "uuid": {
                "type": "string"
            },
            "name": {
                "type": "string"
            }
        },
        "required": [
            "uuid",
            "name"
        ]
    }
}

The index MUST use the identifier 'index'.

Public keys must NOT be stored in the index.

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.

Implementation

A Go implementation of the filesystem layout can be found at https://github.com/wealdtech/go-eth2-wallet-filesystem.

A Go implementation of the Amazon S3 layout can be found at https://github.com/wealdtech/go-eth2-wallet-s3.

Security Considerations

Locations for wallet stores are defined to be within each user's personal space, reducing the possibility of accidental exposure of information. It is, however, still possible for permissions to be set such that this data is world-readable, and applications implementing this EIP should attempt to set, and reset, permissions to ensure that only the relevant user has access to the information.

The names for both wallet and key stores are UUIDs, ensuring that no data is leaked from the metadata.

Copyright

Copyright and related rights waived via CC0.