diff --git a/doc/transaction/grin-transaction.png b/doc/transaction/grin-transaction.png deleted file mode 100644 index cd9dfb03..00000000 Binary files a/doc/transaction/grin-transaction.png and /dev/null differ diff --git a/doc/wallet.md b/doc/wallet.md deleted file mode 100644 index 154c13f7..00000000 --- a/doc/wallet.md +++ /dev/null @@ -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 ` command to work. - -### grin wallet send - -Builds a transaction to send someone some coins. Creates and outputs a transaction. -- add -d to request a destination wallet from the given server address and port, and then push the transaction to the network -- add -s 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. diff --git a/doc/wallet/design/design.md b/doc/wallet/design/design.md new file mode 100644 index 00000000..97905971 --- /dev/null +++ b/doc/wallet/design/design.md @@ -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( +!·wallet: &mut T, +!·show_spent: bool, +!·tx_id: Option, +) -> Result, Error> +where +!·T: WalletBackend, +!·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. + + + + + diff --git a/doc/wallet/design.md b/doc/wallet/design/goals.md similarity index 100% rename from doc/wallet/design.md rename to doc/wallet/design/goals.md diff --git a/doc/wallet/design/wallet-arch.png b/doc/wallet/design/wallet-arch.png new file mode 100644 index 00000000..5a50a1b4 Binary files /dev/null and b/doc/wallet/design/wallet-arch.png differ diff --git a/doc/wallet/design/wallet-arch.puml b/doc/wallet/design/wallet-arch.puml new file mode 100644 index 00000000..1b7895bd --- /dev/null +++ b/doc/wallet/design/wallet-arch.puml @@ -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 \ No newline at end of file diff --git a/doc/wallet/transaction/basic-transaction-wf.png b/doc/wallet/transaction/basic-transaction-wf.png new file mode 100644 index 00000000..acb15283 Binary files /dev/null and b/doc/wallet/transaction/basic-transaction-wf.png differ diff --git a/doc/transaction/grin-transaction.puml b/doc/wallet/transaction/basic-transaction-wf.puml similarity index 53% rename from doc/transaction/grin-transaction.puml rename to doc/wallet/transaction/basic-transaction-wf.puml index 80c12647..56447c30 100644 --- a/doc/transaction/grin-transaction.puml +++ b/doc/wallet/transaction/basic-transaction-wf.puml @@ -2,14 +2,14 @@ title **Current Grin Tranaction Workflow** -Accurate as of Feb 12th, 2018 - Master branch only +Accurate as of Aug 1, 2018 - Master branch only end title actor "Sender" as sender actor "Recipient" as recipient entity "Grin Node" as grin_node -== Phase 1 - Sender Initiation == +== Round 1 == note left of sender 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 4: Create **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 -sender -> sender: Lock **inputs** in wallet -sender -> sender: Store **change_output** in wallet with status "Unconfirmed" 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) - 7: Calculate **fee**: **tx_weight** * 1_000_000 nG - 8: Calculate total blinding excess sum for all inputs and outputs **xS** (private scalar) - 9: Select a random nonce **kS** (private scalar) - 10: Multiply **xS** and **kS** by generator G to create public curve points **xSG** and **kSG** + 8: Calculate **fee**: **tx_weight** * 1_000_000 nG + 9: Calculate total blinding excess sum for all inputs and outputs **xS** (private scalar) + 10: Select a random nonce **kS1** (private scalar) + 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 -sender -> recipient: **UUID**, **inputs**, **change_output**, **fee**, **lock_height**, **kSG**, **xSG** -== Phase 2 - Receiver Initiation == +sender -> recipient: **Slate** +== Round 2 == note right of recipient 1: Check fee against number of **inputs**, **change_outputs** +1 * **receiver_output**) 2: Create **receiver_output** 3: Choose random blinding factor for **receiver_output** **xR** (private scalar) end note -recipient -> recipient: Store **receiver_output** in wallet with status "Unconfirmed" note right of recipient 4: Calculate message **M** = **fee | lock_height ** 5: Choose random nonce **kR** (private scalar) 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**) 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 alt All Okay -recipient --> sender: Okay - **UUID**, **sR**, **xRG**, **kRG** +recipient --> sender: Okay - **Slate** +recipient -> recipient: execute wallet output function **rF** else Any Failure -recipient -> recipient: Remove **receiver_output** from wallet recipient ->x]: Abort recipient --> sender: Error -sender -> sender: Roll back **inputs** and **change_output** [x<- sender: Abort end -== Phase 3 - Sender Confirmation == +== Finalize Transaction == note left of sender 1: Calculate message **M** = **fee | lock_height ** 2: Compute Schnorr challenge **e** = Blake2(**M** | **kRG** + **kSG**) 3: Verify **sR** by verifying **kRG** + **e** * **xRG** = **sRG** 4: Compute Sender Schnorr signature **sS** = **kS** + **e** * **xS** -end note -sender -> recipient: **UUID**, **sS** -== Phase 4 - Receiver Confirmation == -note right of recipient - 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** + 5: Calculate final signature **s** = (**sS**+**sR**, **kSG**+**kRG**) + 6: Calculate public key for **s**: **xG** = **xRG** + **xSG** + 7: Verify **s** against excess values in final transaction using **xG** + 8: Create Transaction Kernel Containing: + Signature **s** Public key **xG** **fee** **lock_height** + excess value **oS** end note -recipient -> recipient: Create final transaction **tx** -recipient -> grin_node: Post **tx** to mempool +sender -> sender: Create final transaction **tx** from **Slate** +sender -> grin_node: Post **tx** to mempool grin_node --> recipient: "Ok" alt All Okay recipient --> sender: "Ok" - **UUID** +sender -> sender: Execute wallet lock function **sF** ...Await confirmation... recipient -> grin_node: Confirm **receiver_output** 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 **change_output** to "Confirmed" 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 --> 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 end diff --git a/doc/wallet/usage.md b/doc/wallet/usage.md new file mode 100644 index 00000000..899fbe1c --- /dev/null +++ b/doc/wallet/usage.md @@ -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 ``. 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`