Offline Wallet CLI

From Veriblock Wiki
Jump to: navigation, search

See Main_Page, Wallet_Encryption

Overview

The Offline Wallet CLI runs completely offline, without any internet or connection to NodeCore.

Source code: https://github.com/VeriBlock/offline-wallet-cli

It ultimately provides a subset of functionality offered by NC_CLI, but it operates without requiring a connection to a full NodeCore instance.

Helpful links:

Compile Offline Wallet CLI

  1. Get source code: https://github.com/VeriBlock/offline-wallet-cli
  2. run gradlew.bat (windows) or ./gradlew build (linux)
  3. This will create zip/tar files in \build\distributions.
  4. Unzip, and run either "offline-wallet-cli" for linux (remember to chmod a+x offline-wallet-cli), or "offline-wallet-cli.bat" for windows.

Usage

Create a new wallet or load an existing wallet

On start, enter a wallet file, such as "Test1.dat".

  • If the wallet exists, then it will be loaded
  • If it does not exist, then the tool will automatically create this new wallet.
Please enter the name of the wallet you want to interact with.
Test1.dat
[Test1.dat]>

The tool has a "current wallet context" that all the commands apply to. This will be in the command prompt, like so:

[Test1.dat]>

To switch to a different wallet, use the "switchwallet" command.

To see the (standard) addresses in a wallet, use the "getalladdresses" command.

Create a new address

Use the Offline Wallet CLI, simply run:

getnewaddress

Receive coins to an address generated offline

Use the NC_CLI connected to a running NodeCore instance holding addresses with a balance to send coins like normal (to send coins to a standard or multisig address generated by the Offline Wallet CLI).

send <amount> <destinationAddress>

NodeCore_CommandLine#send

Note that once an address is created in the Offline Wallet CLI, anyone can send coins to it.

Example:

# In Offline Wallet CLI, create a new address
getnewaddress

#This will create something like:
VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN

#in NC_CLI, send to that from an address with sufficient balance
send 100 VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN

#in NC_CLI (after waiting ~30 seconds for the transaction to get into a block), check the balance:
getbalance VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN

#result: new address VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN now has a balance on the blockchain, even though Offline Wallet CLI never connected to the network

Send a standard (non-multisig) transaction

The Offline Wallet CLI can create a transaction offline using the command "makesignedstandardtx", and then someone can use the NC_CLI to submit that transaction to the network. For example, the following workflow could be used to has an offline wallet which outgoing transactions can be created from:

1.) Have a dedicated computer disconnected from the internet with the Offline Wallet CLI software and the appropriate wallet file

2.) Generate signed transactions on the offline computer and copy them to a thumb drive, write them down manually, etc.

3.) Input those signed transactions to an instance of the normal CLI connected to a synced NodeCore instance on another computer


Example: Send 5 VBK from VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN to V6gqrRU5iJpaBiAFYTwrK8FY46F38g (with an additional transaction fee of 0.0001 VBK).


You will need to know the correct "signature index" for the address you are sending coins from. Transactions on the VeriBlock network from a particular address must occur in incremental signature index order, starting from 0. In other words, the first transaction from an address is at signature index 0, the second transaction will be at a signature index of 1, etc. The current signature index for an address can be acquired from NC_CLI connected to a full NodeCore instance:

#Format:
# sigindex <address>

sigindex VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN
{
  "payload": {
    "addresses": [
      {
        "pool_index": -1,
        "address": "V9tdwBuXBy45E7MYTg54PCiuE9SfP9",
        "blockchain_index": -1
      }
    ]
  },
  "success": true,
  "messages": []
}

# The "pool_index" refers to the signature index of the address accounting for transactions in the mempool and blockchain. An address which hasn't sent any transactions before will have an index of -1, an address which has sent one transaction will have an index of 0, etc. Add one to this number (so in this case, -1 + 1 = 0, this address has not sent any transactions before) to get the signature index to use for the next transaction.

Now that you have the correct signature index, you can generate and sign the standard transaction:

#Format:
# makesignedstandardtx <sourceAddress> <amount> <destinationAddress> <transactionFee> <signatureIndex>

#In the Offline Wallet CLI, make the transaction:
makesignedstandardtx VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN 5 V6gqrRU5iJpaBiAFYTwrK8FY46F38g 0.0001 0

#This returns the transaction hex, and the TxId for easy reference:
Raw signed transaction: 1289020A483046022100A6106B5C1F850BF630C7CF4197F0618F8C86DF021725F7D2079CEC602CD58F11022100EEF1D0386668CD14AD7551ED1BDC193CE76B482FFBAD3C8EAB27F97CE0703E0212583056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C22630801121667CFF95F43FF050E44670FA0A1C427DF6A4E50562FF3189098B6EE01221E0A1667869CF871CA12FCEADEF8FDF49E343AE465615F90251080CAB5EE018A01200D49D5FA4D36FA4EE105978E95F9A49832BCD73D0A27B2E238A132C81044FF24
TxID: 0D49D5FA4D36FA4EE105978E95F9A49832BCD73D0A27B2E238A132C81044FF24

#In the '''NC_CLI''' (connected to a fully synced instance of NodeCore), use the "submittx" command to submit this transaction:
#Format:
# submittx <rawTransaction>
submittx 1289020A483046022100A6106B5C1F850BF630C7CF4197F0618F8C86DF021725F7D2079CEC602CD58F11022100EEF1D0386668CD14AD7551ED1BDC193CE76B482FFBAD3C8EAB27F97CE0703E0212583056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C22630801121667CFF95F43FF050E44670FA0A1C427DF6A4E50562FF3189098B6EE01221E0A1667869CF871CA12FCEADEF8FDF49E343AE465615F90251080CAB5EE018A01200D49D5FA4D36FA4EE105978E95F9A49832BCD73D0A27B2E238A132C81044FF24

#The transaction should be submitted, and visible over the network, such as by running gettransaction in the NC_CLI:
gettransaction 0D49D5FA4D36FA4EE105978E95F9A49832BCD73D0A27B2E238A132C81044FF24

#view the updated address:
getbalance V6gqrRU5iJpaBiAFYTwrK8FY46F38g 

Send a mutlisig transaction

The Offline Wallet CLI can also create multisig transactions offline. View this page as a reference for multisig transactions in general:

How_to_Submit_Multisig_Tx

This will involve several Offline Wallet CLI commands:

Step# Command Comment
1 generatemultisigaddress Initially create the multisig address. This could be done once. Could use either new or existing standard addresses. Often, the private keys to these addresses will be held by separate parties.
2 makeunsignedmultisigtx Create a Tx. This could be done many times given the same multisig address.
3 signhexmessage Holder of the address must sign. Need sufficient number of holders. In most cases, multisig addresses are made from addresses stored by different people/entities in separate wallet files. Each member of the multisig party who wishes to sign the transaction must sign the multisig address and send their signature to a central organizer, who compiles the required number of signatures together into a valid signed multisig transaction and submits it to the network.
4 compilesignedmultisigtx Analogous to NC_CLI submitmultisigtx. Creates the final hex-encoded signed multisig transaction, which must be submitted using the regular CLI to a synced NodeCore instance using the submittx command.

Step 1: generate the address

#Format
#generatemultisigaddress <csvAddresses> <signatureThreshold>

#create a 2 of 3 multisig address:
#IMPORTANT: Record these addresses, and the order for future use
generatemultisigaddress VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN,V6gqrRU5iJpaBiAFYTwrK8FY46F38g,VDEUDoJvuH64PCj7eSNrFXvMy7jRua 2

#result: creates new multisig address "V232ChdFDeZe1LWpZ7oQnPRyNEYqg0"
Checksum created based on V232ChdFDeZe1LWpZ7oQnPRyN
V232ChdFDeZe1LWpZ7oQnPRyNEYqg0

After generating the address, send funds to it

Step 2: Make the transaction (sending from the multisig address to another address)

#Format:
# makeunsignedmultisigtx <sourceAddress> <amount> <destinationAddress> <transactionFee> <signatureIndex>

#In the Offline Wallet CLI, run:
makeunsignedmultisigtx V232ChdFDeZe1LWpZ7oQnPRyNEYqg0 10 VkSWh9FBjm4fpYV5MxkxZbvWJBC3p4 0.0001 0

#This creates the out:
Raw transaction: 0A6308031216A978ED47ADC78A6C52C139BAB4E176AA448797BDBCA21890E2EBDC03221E0A1669EC90EFB324261308F727C59365DE14A03421315EA9108094EBDC038A012018FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448
TxID: 18FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448


Step 3: Have sufficient number of holders sign

#Format:
# signhexmessage <address> <TxId>

Holder 1 signs:

signhexmessage VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN 18FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448

#This creates output like:
VALID
Address: VBCV7zkSKLCxUSLpk2xLTonGZ2d3pN
Message: 18FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448
Public Key: 3056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C
Signature: 3046022100B2E465420198D29AF159D72AB14498BF3F00C22826685AE8824C641BE2618603022100AAB59C97B25DA0D38F694668479AE01AA63B13246406E632C561064A0FAAF024

Holder 2 skips

Holder 3 signs:

signhexmessage VDEUDoJvuH64PCj7eSNrFXvMy7jRua 18FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448

#This creates output like:
VALID
Address: VDEUDoJvuH64PCj7eSNrFXvMy7jRua
Message: 18FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448
Public Key: 3056301006072A8648CE3D020106052B8104000A034200044980EEBB570AF8495EB21FC7882A1A6BE950CE59613523639AED160E2BD8428ED6D9B07C4DCE5B22EF4507952A584CBB072A86F4DC551A9117C0A7DCBAB709A9
Signature: 3044022066F0B59AB598B44A7F7866DB0C8EE96CAAF5A06B30610D22594F1D676C8ADD4C02207A9C207576598090071F106E0460E1DC1DF87506E026D5148577C2ABF3555B74

Step 4: compilesignedmultisigtx from the results of signhexmessage

In the Offline Wallet CLI:

#Format:
# compilesignedmultisigtx <unsignedTransactionHex> <csvPublicKeysOrAddresses> <csvSignaturesHex>

#From step 2:
unsignedTransactionHex = 0A6308031216A978ED47ADC78A6C52C139BAB4E176AA448797BDBCA21890E2EBDC03221E0A1669EC90EFB324261308F727C59365DE14A03421315EA9108094EBDC038A012018FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448

#From step 3 (note that the public keys follow the same order as the addresses which made up the multisig transaction, and since the 2nd member of the multisig group didn't sign, the address is provided in lieu of the public key):
csvPublicKeysOrAddresses = 3056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C,V6gqrRU5iJpaBiAFYTwrK8FY46F38g,3056301006072A8648CE3D020106052B8104000A034200044980EEBB570AF8495EB21FC7882A1A6BE950CE59613523639AED160E2BD8428ED6D9B07C4DCE5B22EF4507952A584CBB072A86F4DC551A9117C0A7DCBAB709A9

#From step 3 (Note to skip the 2nd holder who did not sign, so the double comma indicating a blank signature):
csvSignaturesHex=3046022100B2E465420198D29AF159D72AB14498BF3F00C22826685AE8824C641BE2618603022100AAB59C97B25DA0D38F694668479AE01AA63B13246406E632C561064A0FAAF024,,3044022066F0B59AB598B44A7F7866DB0C8EE96CAAF5A06B30610D22594F1D676C8ADD4C02207A9C207576598090071F106E0460E1DC1DF87506E026D5148577C2ABF3555B74

#In Offline Wallet CLI, run this command:
compilesignedmultisigtx 0A6308031216A978ED47ADC78A6C52C139BAB4E176AA448797BDBCA21890E2EBDC03221E0A1669EC90EFB324261308F727C59365DE14A03421315EA9108094EBDC038A012018FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448 3056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C,V6gqrRU5iJpaBiAFYTwrK8FY46F38g,3056301006072A8648CE3D020106052B8104000A034200044980EEBB570AF8495EB21FC7882A1A6BE950CE59613523639AED160E2BD8428ED6D9B07C4DCE5B22EF4507952A584CBB072A86F4DC551A9117C0A7DCBAB709A9 3046022100B2E465420198D29AF159D72AB14498BF3F00C22826685AE8824C641BE2618603022100AAB59C97B25DA0D38F694668479AE01AA63B13246406E632C561064A0FAAF024,,3044022066F0B59AB598B44A7F7866DB0C8EE96CAAF5A06B30610D22594F1D676C8ADD4C02207A9C207576598090071F106E0460E1DC1DF87506E026D5148577C2ABF3555B74

#This creates output:
Signed multisig transaction: 1AD2030AEA020AA601080112483046022100B2E465420198D29AF159D72AB14498BF3F00C22826685AE8824C641BE2618603022100AAB59C97B25DA0D38F694668479AE01AA63B13246406E632C561064A0FAAF0241A583056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C0A18221667869CF871CA12FCEADEF8FDF49E343AE465615F90250AA401080112463044022066F0B59AB598B44A7F7866DB0C8EE96CAAF5A06B30610D22594F1D676C8ADD4C02207A9C207576598090071F106E0460E1DC1DF87506E026D5148577C2ABF3555B741A583056301006072A8648CE3D020106052B8104000A034200044980EEBB570AF8495EB21FC7882A1A6BE950CE59613523639AED160E2BD8428ED6D9B07C4DCE5B22EF4507952A584CBB072A86F4DC551A9117C0A7DCBAB709A9126308031216A978ED47ADC78A6C52C139BAB4E176AA448797BDBCA21890E2EBDC03221E0A1669EC90EFB324261308F727C59365DE14A03421315EA9108094EBDC038A012018FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448

#In NC_CLI (connected to a synced instance of NodeCore), plug this into submittx
submittx 1AD2030AEA020AA601080112483046022100B2E465420198D29AF159D72AB14498BF3F00C22826685AE8824C641BE2618603022100AAB59C97B25DA0D38F694668479AE01AA63B13246406E632C561064A0FAAF0241A583056301006072A8648CE3D020106052B8104000A03420004792EC0BE87C4FD1DF0EFADF70D90731842AE7EDAAF05644BAB53A4896816FD05F9E8E4537C7D95CCFF18D4746A088282EA0E366464CDF2AC2E0EF89AA9BE663C0A18221667869CF871CA12FCEADEF8FDF49E343AE465615F90250AA401080112463044022066F0B59AB598B44A7F7866DB0C8EE96CAAF5A06B30610D22594F1D676C8ADD4C02207A9C207576598090071F106E0460E1DC1DF87506E026D5148577C2ABF3555B741A583056301006072A8648CE3D020106052B8104000A034200044980EEBB570AF8495EB21FC7882A1A6BE950CE59613523639AED160E2BD8428ED6D9B07C4DCE5B22EF4507952A584CBB072A86F4DC551A9117C0A7DCBAB709A9126308031216A978ED47ADC78A6C52C139BAB4E176AA448797BDBCA21890E2EBDC03221E0A1669EC90EFB324261308F727C59365DE14A03421315EA9108094EBDC038A012018FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448

#In NC_CLI, verify that the transaction shows up:
gettransaction 18FDC9E270CD326BAD29292C676A45932FD015C8D9D705FD0AD3E73047319448

Help

Available commands:
help
        Shows a list of available commands.

getnewaddress
        Generates a new public-private keypair in the current wallet file, and returns the
        corresponding address.

signhexmessage <address> <message>
        Signs the bytes corresponding to the provided hex-encoded <message> with the private key
        of the provided <address>.

makesignedstandardtx <sourceAddress> <amount> <destinationAddress> <transactionFee> <signatureIndex>
        Generates and signs a standard tx sending <amount> VBK to <destinationAddress> with the
        specified <transactionFee> and <signatureIndex>.

generatemultisigaddress <csvAddresses> <signatureThreshold>
        Generates a multisig address from the provided comma-separated addresses with an 'M'
        (number of required signatures) value of <signatureThreshold>

makeunsignedmultisigtx <sourceAddress> <amount> <destinationAddress> <transactionFee> <signatureIndex>
        Generates an unsigned multisig transaction sending <amount> VBK to <destinationAddress>
        with the specified <transactionFee> and <signatureIndex>.

compilesignedmultisigtx <unsignedTransactionHex> <csvPublicKeysOrAddresses> <csvSignaturesHex>
        Compiles the provided <unsignedTransactionHex> unsigned multisig transaction with the
        comma-separated <csvPublicKeysOrAddresses> public keys (for addresses signing the
        transaction) and addresses (for addresses not signing the transaction), and comma-separated
        <csvSignaturesHex> signatures (for the addresses which signed the transaction,
        leaving blanks for the non-signing addresses) to create a signed multisig transaction.


getalladdresses
        Displays all of the (standard) addresses contained in the current wallet file.

encryptwallet <passphrase>
        Encrypts the wallet on disk using the passphrase supplied

decryptwallet <passphrase>
        Decrypts the wallet on disk using the passphrase supplied

unlockwallet <passphrase>
        Unlocks the in-memory wallet using the passphrase supplied thereby enabling the use of
        commands that rely on protected private keys.

lockwallet
        Locks the in-memory wallet thereby disabling the use of commands that rely on
        protected private keys.

switchwallet <walletName>
        Switches context to an alternate wallet

quit
        Exits the application