mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
[WIP] Wallet documentation (#1302)
* doc update * change and reorganise wallet documentation * Redo wallet arch document, update design document with current info, move older design document into 'goals.md' * Redo wallet arch document, update design document with current info, move older design document into 'goals.md'
This commit is contained in:
parent
76f4915bf9
commit
658a686cc1
9 changed files with 495 additions and 93 deletions
Binary file not shown.
Before Width: | Height: | Size: 206 KiB |
|
@ -1,63 +0,0 @@
|
||||||
# Grin - Basic Wallet
|
|
||||||
|
|
||||||
## Wallet Files
|
|
||||||
|
|
||||||
A Grin wallet maintains its state in the following files -
|
|
||||||
|
|
||||||
```
|
|
||||||
wallet.seed # *** passphrase protected seed file (keep this private) ***
|
|
||||||
wallet.dat # wallet outputs (both spent and unspent)
|
|
||||||
wallet.lock # lock file, prevents multiple processes writing to wallet.dat
|
|
||||||
```
|
|
||||||
|
|
||||||
By default Grin will look for these in the current working directory.
|
|
||||||
|
|
||||||
## Basic Wallet Commands
|
|
||||||
|
|
||||||
`grin wallet --help` will display usage info about the following.
|
|
||||||
|
|
||||||
### grin wallet init
|
|
||||||
|
|
||||||
Before using a wallet a new seed file `wallet.seed` needs to be generated via `grin wallet init` -
|
|
||||||
|
|
||||||
```
|
|
||||||
grin wallet init
|
|
||||||
Generating wallet seed file at: ./wallet.seed
|
|
||||||
```
|
|
||||||
|
|
||||||
### grin wallet info
|
|
||||||
|
|
||||||
Some (very) basic information about current wallet outputs can be displayed with `grin wallet info` -
|
|
||||||
|
|
||||||
```
|
|
||||||
grin wallet -p "password" info
|
|
||||||
Using wallet seed file at: ./wallet.seed
|
|
||||||
Outputs -
|
|
||||||
key_id, height, lock_height, status, spendable?, coinbase?, value
|
|
||||||
----------------------------------
|
|
||||||
96805837571719c692b6, 21, 24, Spent, false, true, 50000000000
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
### grin wallet listen
|
|
||||||
|
|
||||||
Starts a listening wallet server. This is needed for the `grin wallet send -d <destination wallet server>` command to work.
|
|
||||||
|
|
||||||
### grin wallet send
|
|
||||||
|
|
||||||
Builds a transaction to send someone some coins. Creates and outputs a transaction.
|
|
||||||
- add -d <destination server> to request a destination wallet from the given server address and port, and then push the transaction to the network
|
|
||||||
- add -s <strategy> to choose between selection strategies. If you're experimenting, or the destination is not reliable, it is currently recommendable to use the strategy `smallest`
|
|
||||||
|
|
||||||
### grin wallet receive
|
|
||||||
|
|
||||||
Replaced by `listen` (see above). The `receive` command might later be recycled to actively accept one or several specific transactions.
|
|
||||||
|
|
||||||
### grin wallet request
|
|
||||||
|
|
||||||
(tbd)
|
|
||||||
|
|
||||||
### grin wallet burn
|
|
||||||
|
|
||||||
*TESTING ONLY*: Burns the provided amount to a known key. Similar to send but burns an output to allow single-party
|
|
||||||
transactions.
|
|
93
doc/wallet/design/design.md
Normal file
93
doc/wallet/design/design.md
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
### Grin Wallet + Library Design
|
||||||
|
|
||||||
|
![wallet design](wallet-arch.png)
|
||||||
|
**High Level Wallet Design Overview**
|
||||||
|
|
||||||
|
The current Grin `wallet` crate provides several layers of libraries, services, and traits that can be mixed, matched and reimplemented to support
|
||||||
|
various needs within the default Grin wallet as well as provide a set of useful library functions for 3rd-party implementors. At a very high level,
|
||||||
|
the code is organized into the following components (from highest-level to lowest):
|
||||||
|
|
||||||
|
* **Command Line Client** - The command line client invoked by `grin wallet [command]`, simply instantiates the other components below
|
||||||
|
and parses command line arguments as needed.
|
||||||
|
* **Web Wallet Client** - [Work In Progress] A web wallet client accessible from the local machine only. Current code can be viewed here:
|
||||||
|
https://github.com/mimblewimble/grin-web-wallet
|
||||||
|
* **Static File Server** - [TBD] A means of serving up the web wallet client above to the user (still under consideration)
|
||||||
|
* **libWallet** - A high level wallet library that provides functions for the default grin wallet. The functions in here can be somewhat
|
||||||
|
specific to how the grin wallet does things, but could still be reused by 3rd party implementors following the same basic principles as grin
|
||||||
|
does. Major functionality is split into:
|
||||||
|
* **Owner API** - An API that provides information that should only be viewable by the wallet owner
|
||||||
|
* **Foreign API** - An API to communicate with other wallets and external grin nodes
|
||||||
|
* **Service Controller** - A Controller that instantiates the above APIs (either locally or via web services)
|
||||||
|
* **Internal Functions** Helper functions to perform needed wallet tasks, such as selecting coins, updating wallet outputs with
|
||||||
|
results from a Grin node, etc.
|
||||||
|
* **libTx** - Library that provides lower-level transaction building, rangeproof and signing functions, highly-reusable by wallet implementors.
|
||||||
|
* **Wallet Traits** - A set of generic traits defined within libWallet and the `keychain` crate . A wallet implementation such as Grin's current
|
||||||
|
default only needs to implement these traits in order to provide a wallet:
|
||||||
|
* **WalletClient** - Defines communication between the wallet, a running grin node and/or other wallets
|
||||||
|
* **WalletBackend** - Defines the storage implementation of the wallet
|
||||||
|
* **KeyChain** - Defines key derivation operations
|
||||||
|
|
||||||
|
### Module-Specific Notes
|
||||||
|
|
||||||
|
A full API-Description for each of these parts is still TBD (and should be generated by rustdoc rather than repeated here). However a few design
|
||||||
|
notes on each module are worth mentioning here.
|
||||||
|
|
||||||
|
##### Web Wallet Client / Static File Server
|
||||||
|
|
||||||
|
This component is not a 3rd-party hosted 'Web Wallet' , but a client meant to be run on the local machine only by the wallet owner. It should provide
|
||||||
|
a usable browser interface into the wallet, that should be functionally equivalent to using the command line but (hopefully) far easier to use.
|
||||||
|
It is currently not being included by a default grin build, although the required listener is currently being run by default. To build and test this
|
||||||
|
component, see instructions on the [project page](https://github.com/mimblewimble/grin-web-wallet). The 'Static File Server' is still under
|
||||||
|
discussion, and concerns how to provide the web-wallet to the user in a default Grin build.
|
||||||
|
|
||||||
|
##### Owner API / Foreign API
|
||||||
|
|
||||||
|
The high-level wallet API has been split into two, to allow for different requirements on each. For instance, the Foreign API would listen on
|
||||||
|
an external-facing port, and therefore potentially has different security requirements from the Owner API, which can simply be bound to localhost
|
||||||
|
only.
|
||||||
|
|
||||||
|
##### libTX
|
||||||
|
|
||||||
|
Transactions are built using the concept of a 'Slate', which is a data structure that gets passed around to all participants in a transaction,
|
||||||
|
with each appending their Inputs, Outputs or Signatures to it to build a completed wallet transaction. Although the current mode of operation in
|
||||||
|
the default client only supports single-user - single recipient, an arbitrary number of participants to a transaction is supported within libTX.
|
||||||
|
|
||||||
|
##### Wallet Traits
|
||||||
|
|
||||||
|
In the current code, a Wallet implementation is just a combination of these three traits. The vast majority of functions within libwallet
|
||||||
|
and libTX have a signature similar to the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
pub fn retrieve_outputs<T: ?Sized, C, K>(
|
||||||
|
!·wallet: &mut T,
|
||||||
|
!·show_spent: bool,
|
||||||
|
!·tx_id: Option<u32>,
|
||||||
|
) -> Result<Vec<OutputData>, Error>
|
||||||
|
where
|
||||||
|
!·T: WalletBackend<C, K>,
|
||||||
|
!·C: WalletClient,
|
||||||
|
!·K: Keychain,
|
||||||
|
{
|
||||||
|
```
|
||||||
|
|
||||||
|
With `T` in this instance being a class that implements the `WalletBackend` trait, which is further parameterized with implementations of
|
||||||
|
`WalletClient` and `Keychain`.
|
||||||
|
|
||||||
|
There is currently only a single implementation of the Keychain trait within the Grin code, in the `keychain` crate exported as `ExtKeyChain`.
|
||||||
|
The `Keychain` trait makes several assumptions about the underlying implementation, particularly that it will adhere to a
|
||||||
|
[BIP-38 style](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) 'master key -> child key' model.
|
||||||
|
|
||||||
|
There are two implementations of `WalletClient` within the code, the main version being the `HTTPWalletClient` found within `wallet/src/client.rs` and
|
||||||
|
the seconds a test client that communicates with an in-process instance of a chain. The WalletClient isolates all network calls, so upgrading wallet
|
||||||
|
communication from the current simple http interaction to a more secure protocol (or allowing for many options) should be a simple
|
||||||
|
matter of dropping in different `WalletClient` implementations.
|
||||||
|
|
||||||
|
There are also two implementations of `WalletBackend` within the code at the base of the `wallet` crate. `LMDBBackend` found within
|
||||||
|
`wallet/src/lmdb_wallet.rs` is the main implementation, and is now used by all grin wallet commands. The earlier `FileWallet` still exists
|
||||||
|
within the code, however it is not invoked, and given there are no real advantages to running it over a DB implementation, development on it
|
||||||
|
has been dropped in favour of the LMDB implementation.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
doc/wallet/design/wallet-arch.png
Normal file
BIN
doc/wallet/design/wallet-arch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
110
doc/wallet/design/wallet-arch.puml
Normal file
110
doc/wallet/design/wallet-arch.puml
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
@startuml grin-wallet-overview
|
||||||
|
skinparam componentStyle uml2
|
||||||
|
|
||||||
|
[Grin Node] as grin_node
|
||||||
|
|
||||||
|
folder "Provided by Grin" as services {
|
||||||
|
component foreign_api [
|
||||||
|
**Foreign API**
|
||||||
|
External-Facing functions
|
||||||
|
- receive_tx, build coinbase
|
||||||
|
]
|
||||||
|
|
||||||
|
component owner_api [
|
||||||
|
**Owner API**
|
||||||
|
Functions used by wallet owner only
|
||||||
|
- retrieve outputs, retrieve txs,
|
||||||
|
get balances, send, etc. . .
|
||||||
|
|
||||||
|
]
|
||||||
|
component libtx [
|
||||||
|
**Transaction Library (libTx)**
|
||||||
|
Lower-Level transaction functions
|
||||||
|
- Build transaction (via Slate), sign,
|
||||||
|
build reward, fees, etc. . .
|
||||||
|
]
|
||||||
|
component libwallet [
|
||||||
|
**Wallet Library (libWallet) **
|
||||||
|
- Higher level wallet functions (select coins,
|
||||||
|
update wallet from node, etc)
|
||||||
|
- Service Controller
|
||||||
|
(instantiate libs, start listeners)
|
||||||
|
]
|
||||||
|
() "Owner HTTP Listener (localhost only)" as owner_http
|
||||||
|
() "Foreign HTTP Listener" as foreign_http
|
||||||
|
() "Owner Single-Use" as owner_single
|
||||||
|
() "Foreign Single-Use" as foreign_single
|
||||||
|
}
|
||||||
|
|
||||||
|
' Trait definitions
|
||||||
|
package "Traits Implemented by Wallets" as traits {
|
||||||
|
database "WalletBackend" as wallet_backend
|
||||||
|
database "KeyChain" as keychain
|
||||||
|
component "WalletClient" as wallet_client
|
||||||
|
}
|
||||||
|
|
||||||
|
note left of wallet_client
|
||||||
|
- Communication layer implementation
|
||||||
|
- Handles underlying communication with grin node
|
||||||
|
or other wallets
|
||||||
|
- HTTP implementation provided currently, (Other,
|
||||||
|
more secure protocols possible.)
|
||||||
|
end note
|
||||||
|
|
||||||
|
note bottom of keychain
|
||||||
|
- Handles all key derivation operations
|
||||||
|
end note
|
||||||
|
|
||||||
|
note bottom of wallet_backend
|
||||||
|
- Implements underlying storage for wallet data
|
||||||
|
- LMDB storage provided in default client, others
|
||||||
|
possible (Flat-file, other DBs, etc)
|
||||||
|
end note
|
||||||
|
|
||||||
|
libtx <--> traits
|
||||||
|
libwallet <--> traits
|
||||||
|
|
||||||
|
note right of traits
|
||||||
|
**Default Wallet simply a struct that provides**
|
||||||
|
**implementations for these 3 traits**
|
||||||
|
end note
|
||||||
|
|
||||||
|
' Client Side
|
||||||
|
'package "Provided as reference implementation" {
|
||||||
|
[Pure JS Wallet Client Implementation] as js_client
|
||||||
|
[Command Line Wallet Client] as cl_client
|
||||||
|
component web_server [
|
||||||
|
V. Light Rust Web Server - Serve static files (TBD)
|
||||||
|
(Provided by default - localhost only)
|
||||||
|
(Serve up pure JS client)
|
||||||
|
]
|
||||||
|
'}
|
||||||
|
|
||||||
|
[External Wallets] as external_wallets
|
||||||
|
[External Wallets] as external_wallets_2
|
||||||
|
|
||||||
|
wallet_client <--> grin_node
|
||||||
|
wallet_client <--> external_wallets_2
|
||||||
|
|
||||||
|
web_server <--> owner_http
|
||||||
|
js_client <-- web_server
|
||||||
|
cl_client <--> owner_single
|
||||||
|
cl_client <--> foreign_single
|
||||||
|
|
||||||
|
owner_single <--> owner_api
|
||||||
|
foreign_single <--> foreign_api
|
||||||
|
|
||||||
|
libwallet <--> libtx
|
||||||
|
|
||||||
|
foreign_api --> libwallet
|
||||||
|
owner_api --> libwallet
|
||||||
|
|
||||||
|
js_client <--> owner_http
|
||||||
|
owner_http <--> owner_api
|
||||||
|
external_wallets <--> foreign_http
|
||||||
|
foreign_http <--> foreign_api
|
||||||
|
|
||||||
|
'layout fix
|
||||||
|
'grin_node -[hidden]- wallet_backend
|
||||||
|
|
||||||
|
@enduml
|
BIN
doc/wallet/transaction/basic-transaction-wf.png
Normal file
BIN
doc/wallet/transaction/basic-transaction-wf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 202 KiB |
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
title
|
title
|
||||||
**Current Grin Tranaction Workflow**
|
**Current Grin Tranaction Workflow**
|
||||||
Accurate as of Feb 12th, 2018 - Master branch only
|
Accurate as of Aug 1, 2018 - Master branch only
|
||||||
end title
|
end title
|
||||||
|
|
||||||
actor "Sender" as sender
|
actor "Sender" as sender
|
||||||
actor "Recipient" as recipient
|
actor "Recipient" as recipient
|
||||||
entity "Grin Node" as grin_node
|
entity "Grin Node" as grin_node
|
||||||
|
|
||||||
== Phase 1 - Sender Initiation ==
|
== Round 1 ==
|
||||||
|
|
||||||
note left of sender
|
note left of sender
|
||||||
1: Create Transaction **UUID** (for reference and maintaining correct state)
|
1: Create Transaction **UUID** (for reference and maintaining correct state)
|
||||||
|
@ -17,66 +17,68 @@ note left of sender
|
||||||
3: Select **inputs** using desired selection strategy
|
3: Select **inputs** using desired selection strategy
|
||||||
4: Create **change_output**
|
4: Create **change_output**
|
||||||
5: Select blinding factor for **change_output**
|
5: Select blinding factor for **change_output**
|
||||||
|
6: Create lock function **sF** that locks **inputs** and stores **change_output** in wallet
|
||||||
|
and identifying wallet transaction log entry **TS** linking **inputs + outputs**
|
||||||
|
(Not executed at this point)
|
||||||
end note
|
end note
|
||||||
sender -> sender: Lock **inputs** in wallet
|
|
||||||
sender -> sender: Store **change_output** in wallet with status "Unconfirmed"
|
|
||||||
note left of sender
|
note left of sender
|
||||||
6: Calculate **tx_weight**: MAX(-1 * **num_inputs** + 4 * **num_change_outputs** + 1, 1)
|
7: Calculate **tx_weight**: MAX(-1 * **num_inputs** + 4 * **num_change_outputs** + 1, 1)
|
||||||
(+1 covers a single output on the receiver's side)
|
(+1 covers a single output on the receiver's side)
|
||||||
7: Calculate **fee**: **tx_weight** * 1_000_000 nG
|
8: Calculate **fee**: **tx_weight** * 1_000_000 nG
|
||||||
8: Calculate total blinding excess sum for all inputs and outputs **xS** (private scalar)
|
9: Calculate total blinding excess sum for all inputs and outputs **xS** (private scalar)
|
||||||
9: Select a random nonce **kS** (private scalar)
|
10: Select a random nonce **kS1** (private scalar)
|
||||||
10: Multiply **xS** and **kS** by generator G to create public curve points **xSG** and **kSG**
|
11: Subtract random value **oS** from **kS1** to create kernel offset **oS**. Calculate **kS** = **kS1** - **oS**
|
||||||
|
12: Multiply **xS** and **kS** by generator G to create public curve points **xSG** and **kSG**
|
||||||
|
13: Add values to **Slate** for passing to other participants: **UUID, inputs, change_outputs,**
|
||||||
|
**fee, amount, lock_height, kSG, xSG, oS**
|
||||||
end note
|
end note
|
||||||
sender -> recipient: **UUID**, **inputs**, **change_output**, **fee**, **lock_height**, **kSG**, **xSG**
|
sender -> recipient: **Slate**
|
||||||
== Phase 2 - Receiver Initiation ==
|
== Round 2 ==
|
||||||
note right of recipient
|
note right of recipient
|
||||||
1: Check fee against number of **inputs**, **change_outputs** +1 * **receiver_output**)
|
1: Check fee against number of **inputs**, **change_outputs** +1 * **receiver_output**)
|
||||||
2: Create **receiver_output**
|
2: Create **receiver_output**
|
||||||
3: Choose random blinding factor for **receiver_output** **xR** (private scalar)
|
3: Choose random blinding factor for **receiver_output** **xR** (private scalar)
|
||||||
end note
|
end note
|
||||||
recipient -> recipient: Store **receiver_output** in wallet with status "Unconfirmed"
|
|
||||||
note right of recipient
|
note right of recipient
|
||||||
4: Calculate message **M** = **fee | lock_height **
|
4: Calculate message **M** = **fee | lock_height **
|
||||||
5: Choose random nonce **kR** (private scalar)
|
5: Choose random nonce **kR** (private scalar)
|
||||||
6: Multiply **xR** and **kR** by generator G to create public curve points **xRG** and **kRG**
|
6: Multiply **xR** and **kR** by generator G to create public curve points **xRG** and **kRG**
|
||||||
7: Compute Schnorr challenge **e** = Blake2(**M** | **kRG** + **kSG**)
|
7: Compute Schnorr challenge **e** = Blake2(**M** | **kRG** + **kSG**)
|
||||||
8: Compute Recipient Schnorr signature **sR** = **kR** + **e** * **xR**
|
8: Compute Recipient Schnorr signature **sR** = **kR** + **e** * **xR**
|
||||||
|
9: Add **sR, xRG, kRG** to **Slate**
|
||||||
|
10: Create wallet output function **rF** that stores **receiver_output** in wallet with status "Unconfirmed"
|
||||||
|
and identifying transaction log entry **TR** linking **receiver_output** with transaction.
|
||||||
end note
|
end note
|
||||||
alt All Okay
|
alt All Okay
|
||||||
recipient --> sender: Okay - **UUID**, **sR**, **xRG**, **kRG**
|
recipient --> sender: Okay - **Slate**
|
||||||
|
recipient -> recipient: execute wallet output function **rF**
|
||||||
else Any Failure
|
else Any Failure
|
||||||
recipient -> recipient: Remove **receiver_output** from wallet
|
|
||||||
recipient ->x]: Abort
|
recipient ->x]: Abort
|
||||||
recipient --> sender: Error
|
recipient --> sender: Error
|
||||||
sender -> sender: Roll back **inputs** and **change_output**
|
|
||||||
[x<- sender: Abort
|
[x<- sender: Abort
|
||||||
end
|
end
|
||||||
== Phase 3 - Sender Confirmation ==
|
== Finalize Transaction ==
|
||||||
note left of sender
|
note left of sender
|
||||||
1: Calculate message **M** = **fee | lock_height **
|
1: Calculate message **M** = **fee | lock_height **
|
||||||
2: Compute Schnorr challenge **e** = Blake2(**M** | **kRG** + **kSG**)
|
2: Compute Schnorr challenge **e** = Blake2(**M** | **kRG** + **kSG**)
|
||||||
3: Verify **sR** by verifying **kRG** + **e** * **xRG** = **sRG**
|
3: Verify **sR** by verifying **kRG** + **e** * **xRG** = **sRG**
|
||||||
4: Compute Sender Schnorr signature **sS** = **kS** + **e** * **xS**
|
4: Compute Sender Schnorr signature **sS** = **kS** + **e** * **xS**
|
||||||
end note
|
5: Calculate final signature **s** = (**sS**+**sR**, **kSG**+**kRG**)
|
||||||
sender -> recipient: **UUID**, **sS**
|
6: Calculate public key for **s**: **xG** = **xRG** + **xSG**
|
||||||
== Phase 4 - Receiver Confirmation ==
|
7: Verify **s** against excess values in final transaction using **xG**
|
||||||
note right of recipient
|
8: Create Transaction Kernel Containing:
|
||||||
1: Verify **sS** by verifying **kSG** + **e** * **xSG** = **sSG**
|
|
||||||
2: Calculate final signature **s** = (**sS**+**sR**, **kSG**+**kRG**)
|
|
||||||
3: Calculate public key for **s**: **xG** = **xRG** + **xSG**
|
|
||||||
3: Verify **s** against excess values in final transaction using **xG**
|
|
||||||
4: Create Transaction Kernel Containing:
|
|
||||||
Signature **s**
|
Signature **s**
|
||||||
Public key **xG**
|
Public key **xG**
|
||||||
**fee**
|
**fee**
|
||||||
**lock_height**
|
**lock_height**
|
||||||
|
excess value **oS**
|
||||||
end note
|
end note
|
||||||
recipient -> recipient: Create final transaction **tx**
|
sender -> sender: Create final transaction **tx** from **Slate**
|
||||||
recipient -> grin_node: Post **tx** to mempool
|
sender -> grin_node: Post **tx** to mempool
|
||||||
grin_node --> recipient: "Ok"
|
grin_node --> recipient: "Ok"
|
||||||
alt All Okay
|
alt All Okay
|
||||||
recipient --> sender: "Ok" - **UUID**
|
recipient --> sender: "Ok" - **UUID**
|
||||||
|
sender -> sender: Execute wallet lock function **sF**
|
||||||
...Await confirmation...
|
...Await confirmation...
|
||||||
recipient -> grin_node: Confirm **receiver_output**
|
recipient -> grin_node: Confirm **receiver_output**
|
||||||
recipient -> recipient: Change status of **reciever_output** to "Confirmed"
|
recipient -> recipient: Change status of **reciever_output** to "Confirmed"
|
||||||
|
@ -84,10 +86,10 @@ sender -> grin_node: Confirm **change_output**
|
||||||
sender -> sender: Change status of **inputs** to "Spent"
|
sender -> sender: Change status of **inputs** to "Spent"
|
||||||
sender -> sender: Change status of **change_output** to "Confirmed"
|
sender -> sender: Change status of **change_output** to "Confirmed"
|
||||||
else Any Error
|
else Any Error
|
||||||
recipient -> recipient: Remove **receiver_output** from wallet
|
recipient -> recipient: Manually remove **receiver_output** from wallet using transaction log entry **TR**
|
||||||
recipient ->x]: Abort
|
recipient ->x]: Abort
|
||||||
recipient --> sender: Error
|
recipient --> sender: Error
|
||||||
sender -> sender: Roll back **inputs** and **change_output**
|
sender -> sender: Unlock **inputs** and delete **change_output** identified in transaction log entry **TS**
|
||||||
[x<- sender: Abort
|
[x<- sender: Abort
|
||||||
end
|
end
|
||||||
|
|
260
doc/wallet/usage.md
Normal file
260
doc/wallet/usage.md
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
# Grin - Basic Wallet
|
||||||
|
|
||||||
|
## Wallet Files
|
||||||
|
|
||||||
|
A Grin wallet maintains its state in an LMDB database, with the master seed stored in a separate file.
|
||||||
|
A wallet directory should contain:
|
||||||
|
|
||||||
|
```
|
||||||
|
wallet.seed # *** passphrase protected seed file (keep this private) ***
|
||||||
|
wallet_data # The lmdb data directory in which wallet outputs and transaction information are stored
|
||||||
|
```
|
||||||
|
|
||||||
|
By default Grin will look for these in the current working directory.
|
||||||
|
|
||||||
|
### Logging + Output
|
||||||
|
|
||||||
|
Logging configuration for the wallet is read from `grin.toml`. To modify the wallet's logging output, copy `grin.toml` from the main grin directory
|
||||||
|
into the current wallet directory, and modify logging parameters. (Only parameters relevant to the wallet will be read.)
|
||||||
|
|
||||||
|
### Switches common to all wallet commands
|
||||||
|
|
||||||
|
##### Grin Node Address
|
||||||
|
The wallet generally needs to talk to a running grin node in order to remain up-to-date and verify its contents. By default, the wallet
|
||||||
|
tries to contact a node at `127.0.0.1:13413`. To change this, provide the `-a` switch to the wallet command, e.g.:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet -a "http://192.168.0.2:1341" info
|
||||||
|
```
|
||||||
|
|
||||||
|
If commands that need to update from a grin node can't find one, they will generally inform you that the node couldn't be reached
|
||||||
|
and the results verified against the latest chain information.
|
||||||
|
|
||||||
|
##### Password
|
||||||
|
|
||||||
|
All keys generated by your wallet are combinations of the master seed + a password. If no password is provided, it's assumed this
|
||||||
|
password is blank. If you do provide a password, all operations will use the seed+password and you will need to password to view or
|
||||||
|
spend any generated outputs. The password is specified with `-p`
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet -p mypassword info
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Data Directory
|
||||||
|
|
||||||
|
You can override the directory to use for wallet files with the `-d` flag, e.g:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet -d ./path/to/other/dir info
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Basic Wallet Commands
|
||||||
|
|
||||||
|
`grin wallet --help` will display usage info and all flags.
|
||||||
|
`grin wallet help [command]` will deplay flags specific to the command, e.g `grin wallet help listen`
|
||||||
|
|
||||||
|
### init
|
||||||
|
|
||||||
|
Before using a wallet a new seed file `wallet.seed` and storage database needs to be generated via `grin wallet init` -
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet init
|
||||||
|
Jul 30 15:25:20.999 INFO This is Grin version 0.3.0 (git testnet3-47-gaa64854), built for x86_64-unknown-linux-gnu by rustc 1.27.0 (3eda71b00 2018-06-19).
|
||||||
|
Jul 30 15:25:20.999 DEBG Built with profile "debug", features "" on Tue, 24 Jul 2018 14:53:51 GMT.
|
||||||
|
Jul 30 15:25:20.999 DEBG Generating wallet seed file at: ./wallet.seed
|
||||||
|
Jul 30 15:25:20.999 INFO Wallet seed file created
|
||||||
|
Jul 30 15:25:21.085 INFO Wallet database backend created
|
||||||
|
```
|
||||||
|
|
||||||
|
### info
|
||||||
|
|
||||||
|
A summary of the wallet's contents can be retrieved from the wallet using the `info` command. Note that the `Total` sum may appear
|
||||||
|
inflated if you have a lot of unconfirmed outputs in your wallet (especially ones where a transaction is initiated by other parties
|
||||||
|
who then never it by posting to the chain). `Currently Spendable` is the most accurate field to look at here.
|
||||||
|
|
||||||
|
```
|
||||||
|
____ Wallet Summary Info as of 49 ____
|
||||||
|
|
||||||
|
Total | 3000.000000000
|
||||||
|
Awaiting Confirmation | 60.000000000
|
||||||
|
Immature Coinbase | 180.000000000
|
||||||
|
Currently Spendable | 2760.000000000
|
||||||
|
--------- | ---------
|
||||||
|
(Locked by previous transaction) | 0.000000000
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### listen
|
||||||
|
|
||||||
|
This opens a listener on the specified port, which will listen for:
|
||||||
|
* Coinbase Transaction from a mining server
|
||||||
|
* Transactions initiated by other parties
|
||||||
|
|
||||||
|
By default the `listen` commands runs in a manner that only allows access from the local machine. To open this port up
|
||||||
|
to other machines, use the `-e` switch:
|
||||||
|
```
|
||||||
|
[host]$ grin wallet -e listen
|
||||||
|
```
|
||||||
|
|
||||||
|
To change the port on which the wallet is listening, use the `-l` flag, e.g:
|
||||||
|
```
|
||||||
|
[host]$ grin wallet -l 14000 listen
|
||||||
|
```
|
||||||
|
|
||||||
|
The wallet will listen for requests until the process is cancelled with `<Ctrl-C>`. Note that external ports/firewalls need to be configured
|
||||||
|
properly if you're expecting requests from outside your local network (well out of the scope of this document).
|
||||||
|
|
||||||
|
|
||||||
|
### send
|
||||||
|
|
||||||
|
This builds a transaction interactively with another running wallet, then posts the final transaction to the chain. As the name suggests,
|
||||||
|
this is how you send Grins to another party.
|
||||||
|
|
||||||
|
The most important fields here are the destination (`-d`) and the amount itself. To send an amount to another listening wallet:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet send -d "http://192.168.0.10:13415" 60.00
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a transaction with the other wallet listening at 192.168.0.10, port 13415 which credits the other wallet 60 grins
|
||||||
|
while debiting the 60 Grin + fees from your wallet.
|
||||||
|
|
||||||
|
It's important to understand exactly what happens during a send command, so at a very basic level the `send` interaction goes as follows:
|
||||||
|
|
||||||
|
1) Your wallet selects a number of unspent inputs from your wallet, enough to cover the 60 grins + fees.
|
||||||
|
2) Your wallet locks these inputs so as not to select them for other transactions, and creates a change output in your wallet for the difference.
|
||||||
|
3) Your wallet adds these inputs and outputs to a transaction, and sends the transaction to the recipient.
|
||||||
|
4) The recipient adds their output for 60 grins to the transaction, and returns it to the sender.
|
||||||
|
5) The sender completes signing of the transaction.
|
||||||
|
6) The sender posts the transaction to the chain.
|
||||||
|
|
||||||
|
Outputs in your wallet will appear as unconfirmed or locked until the transaction hits the chain and is mined and validated.
|
||||||
|
|
||||||
|
Other flags here are:
|
||||||
|
|
||||||
|
* `-s` 'Selection strategy', which can be 'all' or 'smallest'. Since it's advantageous for outputs to be removed from the Grin chain,
|
||||||
|
the default strategy for selecting inputs in Step 1 above is to use as many outputs as possible to consolidate your balance into a
|
||||||
|
couple of outputs. This also drastically reduces your wallet size, so everyone wins. The downside is that the entire contents of
|
||||||
|
your wallet remains locked until the transaction is mined validated on the chain. To instead only select just enough inputs to
|
||||||
|
cover the amount you want to send + fees, use:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet send -d "http://192.168.0.10:13415" -s smallest 60.00
|
||||||
|
```
|
||||||
|
|
||||||
|
* `-f` 'Fluff' Grin uses a protocol called 'Dandelion' which bounces your transaction directly through several listening nodes in a
|
||||||
|
'Stem Phase' before randomly 'Fluffing', i.e. broadcasting it to the entire network. This reduces traceability at the cost of lengthening
|
||||||
|
the time before your transaction appears on the chain. To ignore the stem phase and broadcast immediately:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet send -f -d "http://192.168.0.10:13415" 60.00
|
||||||
|
```
|
||||||
|
|
||||||
|
### outputs
|
||||||
|
|
||||||
|
Simply displays all the the outputs in your wallet: e.g:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet outputs
|
||||||
|
Wallet Outputs - Block Height: 49
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
Key Id Child Key Index Block Height Locked Until Status Is Coinbase? Num. of Confirmations Value Transaction
|
||||||
|
================================================================================================================================================
|
||||||
|
13aea76c742ec6298360 2 1 4 Unspent true 49 60.000000000 37
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
ef619c4cdda170f9a4eb 3 2 5 Unspent true 48 60.000000000 38
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
be5a6f68db3ff4b88786 4 3 6 Unspent true 47 60.000000000 1
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
753a4086bf73246f8206 5 4 7 Unspent true 46 60.000000000 2
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
b2bf4c3e64a67158989f 6 5 8 Unspent true 45 60.000000000 4
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
db427d890fe59824ee64 7 6 9 Unspent true 44 60.000000000 11
|
||||||
|
```
|
||||||
|
|
||||||
|
Spent outputs are not shown by default. To show them, provide the `-s` flag.
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet -s outputs
|
||||||
|
```
|
||||||
|
|
||||||
|
### txs
|
||||||
|
|
||||||
|
Every time an operation is performed in your wallet (recieve coinbase, send, receive), an entry is added to an internal transaction log
|
||||||
|
containing vital information about the transaction. Because the Mimblewimble chain contains no identifying information whatsoever,
|
||||||
|
this transaction log is necessary in order to allow your wallet to keep track of what was sent and received. To view the contents of the
|
||||||
|
transaction log, use the `txs`
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet txs
|
||||||
|
|
||||||
|
Transaction Log - Block Height: 49
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
|
||||||
|
==========================================================================================================================================================================================================================================
|
||||||
|
1 Confirmed Coinbase None 2018-07-20 19:46:45.658263284 UTC true 2018-07-20 19:46:45.658264768 UTC 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
2 Confirmed Coinbase None 2018-07-20 19:46:45.658424352 UTC true 2018-07-20 19:46:45.658425102 UTC 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
3 Confirmed Coinbase None 2018-07-20 19:46:45.658541297 UTC true 2018-07-20 19:46:45.658542029 UTC 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
4 Confirmed Coinbase None 2018-07-20 19:46:45.658657246 UTC true 2018-07-20 19:46:45.658657970 UTC 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
5 Confirmed Coinbase None 2018-07-20 19:46:45.658864074 UTC true 2018-07-20 19:46:45.658864821 UTC 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
6 Recieved Tx 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
```
|
||||||
|
|
||||||
|
To see the inputs/outputs associated with a particular transaction, use the `-i` switch providing the Id of the given transaction, e.g:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet txs -i 6
|
||||||
|
Transaction Log - Block Height: 49
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
|
||||||
|
===========================================================================================================================================================================================================
|
||||||
|
6 Recieved Tx 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Wallet Outputs - Block Height: 49
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
Key Id Child Key Index Block Height Locked Until Status Is Coinbase? Num. of Confirmations Value Transaction
|
||||||
|
================================================================================================================================================
|
||||||
|
a7aebee71fdd78396ae6 9 5 0 Unconfirmed false 0 60.000000000 6
|
||||||
|
------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
##### cancel
|
||||||
|
|
||||||
|
Everything before Step 6 in the send phase above happens completely locally in the wallets' data storage and separately from the chain.
|
||||||
|
Since it's very easy for a sender, (through error or malice,) to fail to post a transaction to the chain, it's very possible for the contents
|
||||||
|
of a wallet to become locked, with all outputs unable to be selected because the wallet is waiting for a transaction that will never hit
|
||||||
|
the chain to complete. For example, in the output from `grin wallet txs -i 6` above, the transaction is showing as `confirmed == false`
|
||||||
|
meaning the wallet has not seen any of the associated outputs on the chain. If it's evident that this transaction will never be posted, locked
|
||||||
|
outputs can be unlocked and associate unconfirmed outputs removed with the `cancel` command.
|
||||||
|
|
||||||
|
Running against the data above:
|
||||||
|
|
||||||
|
```
|
||||||
|
[host]$ grin wallet cancel -i 6
|
||||||
|
[host]$ grin wallet txs -i 6
|
||||||
|
Transaction Log - Block Height: 49
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
|
||||||
|
=======================================================================================================================================================================================================================
|
||||||
|
6 Received Tx - Cancelled 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
|
||||||
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the Receive transaction has been cancelled, and the corresponding output was removed from the wallet. If I were the sender, my change
|
||||||
|
output would have been deleted, and any outputs that were locked for the transaction would again be available for use in another transaction.
|
||||||
|
|
||||||
|
Be sure to use this command with caution, as there are many edge cases and possible attacks that still need to be dealt with, particularly if you're
|
||||||
|
the recipient of a transaction. For the time being please be 100% certain that the relevant transaction is never, ever going to be posted before
|
||||||
|
running `grin wallet cancel`
|
Loading…
Reference in a new issue