From 017c0c6662f26d875957d21f426e5a40249bbac2 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Tue, 25 Aug 2020 15:53:16 +0100 Subject: [PATCH] ZIP 400: Add HTML and regenerate index. --- README.rst | 1 + index.html | 1 + zip-0400.html | 515 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 517 insertions(+) create mode 100644 zip-0400.html diff --git a/README.rst b/README.rst index f07a453b..5b534e3d 100644 --- a/README.rst +++ b/README.rst @@ -92,6 +92,7 @@ Index of ZIPs 307 Light Client Protocol for Payment Detection Draft 308 Sprout to Sapling Migration Final 310 Security Properties of Sapling Viewing Keys Draft + 400 Wallet.dat format Draft 401 Addressing mempool denial-of-service Final 1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete 1002 Opt-in Donation Feature Obsolete diff --git a/index.html b/index.html index b7fc2175..23983791 100644 --- a/index.html +++ b/index.html @@ -65,6 +65,7 @@ 307 Light Client Protocol for Payment Detection Draft 308 Sprout to Sapling Migration Final 310 Security Properties of Sapling Viewing Keys Draft + 400 Wallet.dat format Draft 401 Addressing mempool denial-of-service Final 1001 Keep the Block Distribution as Initially Defined — 90% to Miners Obsolete 1002 Opt-in Donation Feature Obsolete diff --git a/zip-0400.html b/zip-0400.html new file mode 100644 index 00000000..f6917d2f --- /dev/null +++ b/zip-0400.html @@ -0,0 +1,515 @@ + + + + ZIP 400: Wallet.dat format + + + +
+
ZIP: 400
+Title: Wallet.dat format
+Owners: Alfredo Garcia <oxarbitrage@gmail.com>
+Status: Draft
+Category: Wallet
+Created: 2020-05-26
+License: MIT
+

Terminology

+

The key words "MUST" and "MAY" in this document are to be interpreted as described in RFC 2119. 1

+
+

Abstract

+

This proposal defines the current format used in zcashd for wallet persistent storage, commonly known as wallet.dat.

+
+

Motivation

+

The process of saving wallet data into disk is currently unspecified. The key-values used in the current implementation are undocumented, and their structure and functionality are unknown without a deep analysis of the involved source code. This document details the schema and the mechanics of the wallet database. This is an informational document, no changes will be done to the source code.

+
+

Specification

+

Zcash stores wallet information in a Berkeley database (BDB) 2 commonly known as wallet.dat. The main purpose of this is the persistence of public and private keys the user created and the ability to recover the wallet state after a node restart. This file also allows the migration of user information from one node to another by moving the database to the corresponding new data directory, assuming both zcashd instances are running the same or similar version. A re-index may be necessary after this operation.

+

The current database is a key-value store where keys and values can have multiple data types in binary format. The first data found in a database key is always the property name, the rest of the key is generally used to identify a record, for example:

+
<------ KEY ----+- VALUE ->
+---------------------------
+| zkey | pubkey | privkey |
+---------------------------
+

Here zkey is the property name located at the first position of the database key; the public key is also part of the database key, and it is located in the second position; the private key is saved in the database value column at the first position.

+

Schema

+

According to Zcash v3.0.0-rc1 the following key-values can be found: the property names in bold mean only one instance of this type can exist in the entire database, while the others, suffixed by '*' can have multiple instances. Keys and Values columns of the table contain the types that the stored data is representing. Included also there are the variable names hoping it will add some clarity to what the stored data is representing.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionKeysValues
acc*Account data +
    +
  1. string strAccount
  2. +
+
+
    +
  1. CAccount account
  2. +
+
acentry*Track internal transfers between accounts in the same wallet +
    +
  1. string strAccount
  2. +
  3. uint64_t nNumber
  4. +
+
+
    +
  1. CAccountingEntry acentry
  2. +
+
bestblockThe current best block of the blockchain. +
    +
  1. CBlockLocator locator
  2. +
+
chdseedEncrypted HD seed +
    +
  1. uint256 seedFp
  2. +
+
+
    +
  1. vector<unsigned char> vchCryptedSecret
  2. +
+
ckey*Encrypted transparent pubkey and private key. +
    +
  1. vector<unsigned char> vchPubKey
  2. +
+
+
    +
  1. vector<unsigned char> vchPrivKey
  2. +
+
csapzkey*Encrypted Sapling pubkey and private key. +
    +
  1. libzcash::SaplingIncomingViewingKey ivk
  2. +
+
+
    +
  1. libzcash::SaplingExtendedFullViewingKey extfvk
  2. +
  3. vector<unsigned char> vchCryptedSecret
  4. +
+
cscriptSerialized script, used inside transaction inputs and outputs +
    +
  1. uint160 hash
  2. +
+
+
    +
  1. CScript script
  2. +
+
czkey*Encrypted Sprout pubkey and private key. +
    +
  1. libzcash::SproutPaymentAddress addr
  2. +
+
+
    +
  1. uint256 rkValue
  2. +
  3. vector<unsigned char> vchCryptedSecret
  4. +
+
defaultkeyDefault Transparent key. +
    +
  1. CPubKey CWallet::vchDefaultKey
  2. +
+
destdata*Adds a destination data tuple to the store. +
    +
  1. std::string strAddress
  2. +
  3. std::string strKey
  4. +
+
+
    +
  1. std::string strValue
  2. +
+
hdchainHierarchical Deterministic chain code, derived from seed. +
    +
  1. CHDChain chain
  2. +
+
hdseed*Hierarchical Deterministic seed. 4 +
    +
  1. uint256 seedFp
  2. +
+
+
    +
  1. RawHDSeed rawSeed
  2. +
+
key*Transparent pubkey and privkey. +
    +
  1. CPubKey vchPubKey
  2. +
+
+
    +
  1. CPrivKey pkey
  2. +
+
keymeta*Transparent key metadata. +
    +
  1. CPubKey vchPubKey
  2. +
+
+
    +
  1. CKeyMetadata keyMeta
  2. +
+
minversionWallet required minimal version.
mkeyMaster key, used to encrypt public and private keys of the database. +
    +
  1. unsigned int nID
  2. +
+
+
    +
  1. CMasterKey kMasterKey
  2. +
+
name*Name of an address to insert in the address book. +
    +
  1. string strAddress
  2. +
+
+
    +
  1. string strAddress
  2. +
+
orderposnextIndex of next tx. +
    +
  1. int64_t nOrderPosNext
  2. +
+
pool* +
    +
  1. int64_t nIndex
  2. +
+
+
    +
  1. CKeyPool keypool
  2. +
+
purpose*Short description or identifier of an address. +
    +
  1. string strAddress
  2. +
+
+
    +
  1. string strPurpose
  2. +
+
sapzaddr*Sapling z-addr Incoming Viewing key and address. +
    +
  1. libzcash::SaplingPaymentAddress addr
  2. +
+
+
    +
  1. libzcash::SaplingIncomingViewingKey ivk
  2. +
+
sapextfvk*Sapling Extended Full Viewing Key
sapzkey*Sapling Incoming Viewing Key and Extended Spending Key +
    +
  1. libzcash::SaplingIncomingViewingKey ivk
  2. +
+
+
    +
  1. libzcash::SaplingExtendedSpendingKey key
  2. +
+
tx*Store all transactions that are related to wallet. +
    +
  1. uint256 hash
  2. +
+
+
    +
  1. CWalletTx wtx
  2. +
+
versionThe CLIENT_VERSION from clientversion.h. +
    +
  1. int nFileVersion
  2. +
+
vkey*Sprout Viewing Keys. +
    +
  1. libzcash::SproutViewingKey vk
  2. +
+
+
    +
  1. char fYes
  2. +
+
watchs*Watch-only t-addresses. +
    +
  1. CScript script
  2. +
+
+
    +
  1. char fYes
  2. +
+
witnesscachesizeShielded Note Witness cache size. +
    +
  1. int64_t nWitnessCacheSize
  2. +
+
wkey*Wallet key.
zkey*Sprout Payment Address and Spending Key. +
    +
  1. libzcash::SproutPaymentAddress addr
  2. +
+
+
    +
  1. libzcash::SproutSpendingKey key
  2. +
+
zkeymeta*Sprout Payment Address and key metadata. +
    +
  1. libzcash::SproutPaymentAddress addr
  2. +
+
+
    +
  1. CKeyMetadata keyMeta
  2. +
+
+
+

Functionality

+

When a zcashd node built with wallet support is started for the first time, a new wallet database is created. By default the node will automatically execute wallet actions that will be saved in the database at the first flush time.

+

The following flow will happen when a node with wallet support is started for the first time:

+
    +
  • DEFAULT_KEYPOOL_SIZE (100 by default) keys will be added to the pool, creating 100 records with pool as property name (first value of database key).
  • +
  • Also 100 key properties will be added.
  • +
  • 100 keymeta.
  • +
  • Wallet will create a default transparent key to receive, this will be also added as key, pool and keymeta properties.
  • +
  • This default key is also added as a defaultkey property.
  • +
  • The last action created an entry in the address book that is reflected in the database by the name and purpose properties.
  • +
  • If the wallet is created with HD support, it will have additional properties hdseed and hdchain that will be saved.
  • +
  • version, minversion, witnesscachesize and bestblock properties are added. These are settings and state information: the bestblock property is a good example of the database being populated that is happening without any user interaction, but it will just update as the best block of the current chain changes.
  • +
+

At any time after the database is created, new properties can be added as the wallet users perform actions. For example, if the user creates a new Sapling address with the RPC command z_getnewaddress then new records with properties sapzkey and sapzkeymeta will be added to the database.

+

In zcashd, database changes do not happen immediately but they are flushed in its own thread by ThreadFlushWalletDB() function periodically to avoid overhead. The internal counter nWalletDBUpdated is increased each time a new write operation to the database is done, this is compared with the last flush in order to commit new stuff.

+

When the node goes down for whatever reason the information in the wallet database SHOULD persist in the disk; the next time the node starts, the software will detect the database file, read from there and add the values into memory structures that will guarantee wallet functionality.

+

Transactions

+

The wallet database will not save all the transactions that are happening in the blockchain however it will save all transactions where wallet keys are involved. This is needed for example to get balances. Therefore the wallet must have all the transactions related to a key to compute the final value of coin available in the derived address.

+

The tx property will hold the transaction-related data with the transaction hash as the key and the full transaction as the value.

+
+

Wallet state and transaction reordering

+

Transactions are saved in the database tx key as they arrive, this means transactions have a sequence. The set of all transactions from the begging to a specified timestamp is the wallet state at that instant. Wallet state is important among other things to get current balance for a wallet or address.

+

In the blockchain, transactions can be invalidated by rollbacks; wallet code will handle this by updating the transactions in the memory database. New state needs to be reflected in the disk database, this is done in zcashd by the flag fAnyUnordered where if true at start time, will launch a rescan over all transactions again.

+
+

Wallet Recovery

+

The wallet database file may become corrupted. There are utilities in the zcutil/bin directory that may help with recovering it if this happens. Please ask for help on the Zcash forum or Community Discord.

+
+

Wallet Encryption

+

Encryption will not be discussed in this document in detail as it is expected for the algorithm to change in the future according to the Wallet format ZIP issue: 3.

+

For a deeper understanding of the current encryption mechanism please refer to 5

+
+
+
+

References

+ + + + + + + +
1Key words for use in RFCs to Indicate Requirement Levels
+ + + + + + + +
2Oracle Berkeley Database
+ + + + + + + +
3ZIP 400 issue
+ + + + + + + +
4ZIP 32: Shielded Hierarchical Deterministic Wallets
+ + + + + + + +
5Database key encryption implementation
+
+
+ + \ No newline at end of file