User Guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 17

Securing Digital Assets - Bitcoin Full Node API for kdb+
Jeremy Lucid
September 11, 2018
Table of Contents
1 Introduction ............................................ 1
2 Why run a Full Node ....................................... 2
3 Running and Connecting to a Full Node ............................ 3
3.1 Conguring ......................................... 3
3.2 Installingtheqlibrary................................... 4
3.3 Watchonlyaddresses.................................... 5
3.4 AddressBalances...................................... 5
3.5 TransactionIDs....................................... 6
4 Running Bitcoin Core Wallet in Offline Mode ......................... 7
4.1 Addressgeneration..................................... 8
4.2 Encryptedwallet ...................................... 8
4.3 Creatingawalletbackup.................................. 9
4.4 Multi-SignatureWallet................................... 10
4.5 ProofofOwnership..................................... 11
5 Receiving and Sending funds securely ............................. 12
5.1 Createareceiveaddress .................................. 12
5.2 ConrmingReceivedFunds ................................ 12
5.3 CreateTransaction..................................... 14
5.4 SignTransaction ...................................... 15
5.5 BroadcastTransaction................................... 16
5.6 Sendingfromahotwallet ................................. 17
1 Introduction
Bitcoin is a peer-to-peer, globally distributed and decentralised payments network where each par-
ticipant computer in the network runs a software which implements the Bitcoin protocol. This
protocol is used to control the issuance and secure transfer of bitcoin (BTC) tokens, the native cur-
rency of the network. In the original Satoshi whitepaper [1], Bitcoin is presented as an ”electronic
cash” which can be used in a permission-less way and transacted with across the internet without
requiring a trusted third party. As a new form of money, not issued by a government or central
authority, Bitcoin has often been accessed by its ability to perform the three traditional functions
1
of money: store of value, medium of exchange and unit of account.
Of these functions, the store of value proposition is one of the most interesting. Historically,
stores of value have been associated with scarce tangible commodities like gold, however, while
intangible, bitcoin shares with gold the property of scarcity, albeit digital. Specifically, the rules
of the Bitcoin software ensure that bitcoin tokens exhibit a strict digital scarcity, with a maximum
total cap and disinflationary supply schedule which is mathematically regulated, predictable and
unchangable. Regardless of demand from investors and exchanges, new bitcoin supply remains
inelastic, in that the number of bitcoins mined into existence, roughly ever ten minutes, is inde-
pendent of demand. Even the ever increasing growth of the bitcoin mining industry, together with
technological advancements in bitcoin mining, cannot increase supply beyond what the protocol
rules permit. This strict adherence to a dis-inflationary monetary policy has likened Bitcoin to a
’digital-gold’, or ’hard money’ in monetary economics. In addition, the property of being purely
digital, and software driven, in turn makes Bitcoin highly extensible, meaning it can evolve and be
improved upon over time. Today, this extensibility can be clearly seen in the continued development
taking place on both the base protocol and layer-two protocols, such as the lightening network [2].
While exposure and usage of Bitcoin is increasing for both retail and institutional investors, still
many have expressed concern about how best to store this digital asset in a way which is secure
and legally compliant. Although many secure and user-friendly options such as hardware-wallets
are available for retail investors, enabling self custody, suitable third party Custodian services for
institutions are less further developed. In response to demand, specialised ’Crypto-Custodian’ ser-
vices are currently being developed by Nomura and Ledger, Xapo, Gemini and Coinbase. For such
Custodians, some of the major challenges include
How best to safeguard such assets from a cyber security aspect. For example, making use of
cold storage solutions and multi-signature wallets.
The technological infastructure required for maximum privacy and trust, notably full nodes
and wallet software.
The end-to-end process of receiving funds, implementing access-control, managing funds and
providing auditable proof of ownership
One of the most essential and core tools for addressing these challenges are Bitcoin full nodes,
the topic of this paper. In particular, the following chapters will explore some of the general key
concepts and best practice methodologies with regards to Bitcoin security and full nodes. This
paper will demonstrate usage of the qbitcoind library, a q library designed to interact with the
Bitcoin Core full node and wallet implementations. While this demonstration focuses on Bitcoin,
the concepts can largely be applied across a wide range of cryptocurrency assets.
2 Why run a Full Node
Computers which participate in the Bitcoin network are called nodes, and those which fully verify
all of the rules of Bitcoin are called full nodes. These nodes are an integral software component of
the Bitcoin network and along with validating all transactions and blocks, also help relay them to
other nodes. The full node software is essential for users who wish to use Bitcoin in a trustless way
to maximise security, privacy and avail of the full Bitcoin functionality. Therefore, this software is
2
often run by individual Bitcoin users, miners, cryptocurrency exchanges, wallet providers, payment
processors and blockchain analytics providers.
Without running a full node, a user would be dependant on third party services, such as blockchain
explorer services, for all transactional information, block information and address balance infor-
mation. This reliance on a third party could result in receiving misleading information, or open
the possibility for man-in-the-middle attacks. Even the act of requesting transactional information
from a third party introduces a risk of revealing sensitive transactional and account information.
By running a full node, users can create their own transactions, monitor all incoming and outgoing
funds, confirm that all blocks and transactions follow the consensus rules, that there have been
no double spends, that the correct signatures are present on transactions, and that transactions
and blocks are in the correct data format. While maintaining a full node has associated hardware
requirements in terms of memory and bandwidth, see Full Node Setup, these costs can be viewed
as the cost of certainty, privacy and security when using Bitcoin.
In the following sections, some of the most recommended security practices for running a full
node securely and managing the core wallet will be described, together with examples on how to
perform particular actions using the qbitcoind library. This library can be used to communicate
with a node running on the same server. While qbitcoind is designed to be a convenient option for
q enthusiasts, dealing primariliy with q dictionary, list and table structures, the bitcoin-cli software
(a command line based RPC tool) should still be considered the most secure and functional.
3 Running and Connecting to a Full Node
The most popular and trusted implementation of full nodes is called Bitcoin Core, and its latest
release can be found on Github. To install and run a Bitcoin Core full node (bitcoind) follow the
instructions as described on the following webpage, Install. Upon startup the full node will connect
to multiple peers and begin downloading and validating the Bitcoin blockchain. In this paper, the
node will be used to perform the following tasks.
Creating watch-only wallets, allowing address balances to be monitored without compromising
security
Confirming the settlement of incoming funds and viewing transactional information on the
Bitcoin blockchain
Creating and broadcasting transactions which were signed off-line
3.1 Configuring
The Bitcoin Core implementation, bitcoind, is a headless daemon which syncs the Bitcoin blockchain
on startup and provides a JSON-RPC interface to enable easy integration with other software or
payment systems. It can be interacted with by using the Bitcoin command line utility, bitcoin-cli,
or via HTTP JSON-RPC commands. To enable communication via JSON-RPC set the server=1
value in the bitcoin.conf file prior to startup, as shown below. By default, bitcoind will only
accept connections from other processes running on the same machine, and requires basic access
authentication when being communicated with. To enable username and password authentication,
set the rpc username and password values in the bitcoin.conf file before running the daemon.
3
# Instructions to be added to the bit coin . conf file
# [ rpc ]
# A cce pt co mma nd line and JSON - RPC com mands .
server =1
rp cus er = < username >
rpcpa ssword = < password >
# Sta rting bi tcoind on the comm and line
$bit co in d - d aemo n
3.2 Installing the q library
To load the qbitcoind library follow the instructions given on Github. The library can be loaded
using two methods, either by using the standard library loading package qutil, or by simply loading
the load.q script in the lib folder, \l load.q. Once loaded into a q session, this library can be
used to communicate directly with the node running on the localhost. Connections will only be
accepted after the rpc username and password values have been set. To set these credentials use the
.bitcoind.initPass function, as shown below, and ensure the values match those in the bitcoin.conf
file. To confirm authentication with the node is working correctly, run a simple command like
.bitcoind.getblockcount to retrieve the current block height.
q ). utl . r equi re "qbitcoind" // or q )\ l / path / to / bitc oind / lib / load . q
q).bitcoind.initPass["MyUserName";"MyPassword"]
q ). b it co ind . g et bl oc kc ou nt []
result| 522825
error |
id | 0
To confirm the node has indeed made connections to other nodes on the network, call the
.bitcoind.getnetworkinfo function with no arguments. Below is shown a typical output of this
function, highlightng that 80 connections have been created with other network peers.
q ). b it co ind . g et ne tw or ki nfo [][ `result]
ve rsion | 160000 f
subversion | "/ Satoshi :0.16. 0 / "
protocolversion | 70015 f
localservices | "000000000000040d"
localrelay | 1b
timeoffset | 0f
networkactive | 1b
conne ct ion s | 80 f
4
3.3 Watch only addresses
When the Bitcoin Core full node software is running online it is continuously validating transactions
and blocks, but it also has fully in-built wallet functionality allowing the user to create receive
addresses and manage funds. There are, however, security concerns to consider when using the
wallet functionality while the node is online. In particular, it is not recommended to generate or
store bitcoin private keys on an online computer as this greatly increases the risk of cyber theft.
A much better solution is to either generate the addresses on an offline hardware wallet device, or
run another instance of the bitcoind software on a completely offline computer, so as to securely
generate valid bitcoin addresses and sign transactions using the wallet functionality. To see how to
do this, go to Section - Offline wallet.
The online node can then be used, in conjunction, to monitor those addresses for incoming and
outgoing transactions, and to broadcast transactions which were signed offline. While this practice
will be explained in more detail in coming sections, for now we will focus on using the online full node
for creating watch-only wallets. Wallet addresses generated offline can be imported into the online
bitcoin node while keeping the private keeps on the offline wallet. Below the .bitcoind.importaddress
function is used to load an address into an account called ”Watch Only Addr One”.
// Arguments:
// 1. " scrip t " ( string , req uired ) The hex - encod ed sc ript ( or addres s )
// 2. " label " ( string , optional , defau lt ="") An o ption al label
// 3. rescan ( boolean , optional , d efault = true ) R escan the wallet
// 4. p2sh ( boolean , optional , default = false ) Add the P2SH ve rsion
q) Address :"37cCd24chWjXSi7xmQahTzyGjbJauTp9xq"
q ). b itcoin d . importaddress [ Add ress ;" Watch Only Addr One " ]
3.4 Address Balances
Once the previous watch-only address has been loaded, the wallet will continue to track all ingoing
and outgoing transactions to this address and keep track of the total balance. The balance can be
viewed using the .bitcoind.getbalance function, which takes three optional argument: the account
name, the minimum number of confirmations a transaction should have to be included, and whether
to include watch only addresses or not. In this case, we can specify the same wallet account name
as above, a minimum number of confirmations of 6 and a boolean value of 1b to include watch
only addresses. The balance on the address is reported in the results field. By using the node to
determine address balances, multiple accounts (whose private keys are kept in cold storage) can be
kept track of securely and without requiring a third party.
// Arguments:
// 1. accou nt ( string , optiona l , de fault ="") The acou nt name
5
// 2. m in co nf ( int , o pt ion al , d ef au lt = "") Min nu mb er of co n fi r ma ti o ns
// 3. w at ch on ly ( bool ea n , opti on al , de fa ult =0 b ) I nc lude w at ch on ly
q ). b itcoin d . g etbalance [" Wat ch Only Addr One " ;6;1 b]
result| 0.1245
error |
id | 0
3.5 Transaction IDs
Transaction IDs (txid) are identification numbers associated with transactions on the Bitcoin
blockchain. They are always 32 bytes long and encoded in hexidecimal format. In Section -
Broadcast Transaction, a sample txid is returned when a new transaction is broadcast to the
Bitcoin network from the full node using the .bitcoind.sendrawtransaction function. To perform
a lookup against the local copy of the blockchain for this particular txid, we can use the .bit-
coind.getrawtransaction or .bitcoind.gettransaction functions, as shown below.
// Arguments:
// 1. " txid " ( string , requi red ) The tr ansaction id
// 2. verbos e ( bool , optional , d efaul t = false )
// If false , return string , else json object
// 3. " b lockhash " ( string , opti onal ) The block in which
// to look for the tr a n saction
t:"78889f97c5d105b5b5a13807d10438bab700db08cb88581a1f8bb3c10ad368e0"
q ). b it co ind . g et ra wt ra ns ac ti on [ t ;1][ `result]
txid | " 78889 f 97 c5d1 05 b5 b5 a138 07 d1 04 38 bab7 00 db 08 cb88 5 ... "
hash | " 8208 dc5 4d 4a 44 d2d9 72 a5 12 46fc c6 1d 38 91 2f8 10 15 21 5 ... "
ve rsion | 2f
size | 192 f
vsize | 110 f
locktime | 0f
// Arguments:
// 1. " txid " ( string , requi red ) The tr ansaction id
// 2. " i nc lu de _wat ch on ly " ( bool , op tio na l , d efau lt = fal se ) W he the r to
// inclu de watch - only address es in bala nce c alculation and d etails []
q ). b it co ind . g et tr an sa ct ion [ t ;1 b ][ `result]
amount | -0.01071
fee | -2.73 e -06
confirmations | 3540f
blockhash | " 0 00000 00 00 00 00 00 00 27 32151 19 1 c6f43487f591 ... "
bloc kindex | 2825 f
blo cktime | 1 .532 991 e +09
6
txid | "78889f97c5d105b5b5a13807d10438bab700db08..."
walletconflicts | ()
time | 1 .53298 8 e +09
timerec ei ved | 1 .532 988 e +09
bip125 - r e p laceable | " no "
4 Running Bitcoin Core Wallet in Offline Mode
The Bitcoin Core software contains a secure digital wallet which can be used to generate wallet
addresses, store private keys, and create valid transactions. Running the bitcoin core wallet in an
offline mode is a highly recommended and necessary step to help mitigate the risk of cyber attacks,
malicous software, and help keep funds secure. This approach, also known as cold storage, involves
running the wallet software and storing the recovery wallet file (wallet.dat) in a secured place that
is not connected to the internet. This security step is followed by Custodians such as the Swiss
Crypto Vault, Xapo and multiple cryptocurrency exchanges. To run a bitcoin core wallet in offline
mode, instruct it to connect to the localhost, as shown below.
$bit co ind - c onnec t =0
As in the previous case, when the node was run in an on-line mode, the same queries can be
used to confirm the blockchain had not been downloaded, nor any connections made with other
nodes.
q ). utl . r equi re "qbitcoind"
q).bitcoind.initPass["MyUserName";"MyPassword"]
q ). b it co ind . g et bl oc kc ou nt []
result | 0
error |
id | 0
q ). b it co ind . g et ne tw or ki nfo [][ `result]
ve rsion | 160000 f
subversion | "/ Satoshi :0.16. 0 / "
protocolversion | 70015 f
localservices | "000000000000040d"
localrelay | 1b
timeoffset | 0f
networkactive | 1b
conne c t i o n s | 0f
7
4.1 Address generation
In order for a user to receive and store bitcoin payments, a valid bitcoin address needs to be created
by the wallet and associated with a given account. Multiple addresses can be used to segregate the
funds of a given user, and separate users. Below the .bitcoind.getnewaddress function is used to
generate a new valid address and associate it with the account ”Account One”.
// Arguments:
// 1. " accou nt " ( string , optio n al ) DEPRECATE D . The a ccount
// name for the ad dress to be linked to . If not provided ,
// the default account "" is used . It can also be set to
// the empty string "" to represe n t the default account .
// The account does not need to exist , it will be created if
// there is no account by the given name .
// 2. " addres s_ ty pe " ( string , o ptiona l ) The a ddre ss type to use .
// O ption s are " l egac y " , " p2sh - segwit " , and " bech32 ". Defau lt is
// set by - a dd resstype .
q ). b itcoin d . getnewaddress [ " A cco unt One " ;" bech 32 " ]
result| "bc1qxuhlv9kpq9zz07xm0at2w44ene6la7qm2ew6un"
error | 0 n
id | 0f
4.2 Encrypted wallet
In addition to cold storage, one of the main security features of the Bitcoin core wallet is the ability
to encrypt the wallet.dat file which contains the key pairs for each address, account information,
transaction information and more. When the wallet is encrypted then the private keys cannot
be viewed or used to create a transaction, even by someone with physical access to the machine.
Only when the wallet is decrypted can private keys be viewed and transactions generated. The
wallet.dat file can be encrypted using a pass phrase, as shown below. Note this will not protect
against keylogging hardware or software.
// Arguments:
// 1. " p a ssphrase " ( stri ng ) The pass phra se to encryp t wal let with .
// It must be at least 1 character , but sh ould be long .
q ). b itcoin d . encryptwallet [ " My En cryp t P as s P hr as e " ]
Once the wallet is encrypted, a user with physical access is still unable to view the private key
of any address without entering the correct decrypt pass phrase. To illustrate, below an attempt is
made to display the private key associated with a particular wallet address which is unsuccessful.
8
// Arguments:
// 1. " addre ss " ( string , r equired )
// The bitcoin addr ess for the pr ivate key
q) R :. bitco ind . dumppri v k e y [ "3JtpCVqn8cXseSCXLEYdYwvxziSYQSabGd"]
q)R[`er ror ][ `messa ge ]
" Error : Please enter the wallet passphr ase with walletpass p h r a se first "
To minimise risk while the wallet is decrypted, a timer can be set at the time of decryption
allowing the wallet to be accessed for a brief period of time. Below, the wallet is decrypted for a
period of 30 seconds using the .bitcoind.walletpassphase function.
// Arguments:
// 1. " p a ssphrase " ( string , requ ired ) The wallet passphr a s e
// 2. tim eout ( numeric , re q uired ) The time to keep the
// decry p t i on key in seconds ; cap ped at 10000000 0 (˜3 years ).
q ). bitcoi n d . wal l e t p a s s p h rase [ " My En cryp t P as s P hr as e " ;30]
If after entering the wallet pass phrase the transaction task is completed prior to the timeout
time being reached, the wallet can be locked again immediately and the encryption key removed
from memory using the .bitcoind.walletlock function.
// Remov es the wall et encryp t i on key from memory , lock ing the wallet .
// After calling this method , you will need to call walletpass p h r a s e
// again bef ore being able to call any me thods which require the
// wallet to be unlo cked .
q ). b it co ind . wall et lo ck []
4.3 Creating a wallet backup
To mitigate the risk of data loss due to either computer failures or human mistakes, additional
recovery wallet files can be created at any time and stored offline across multiple physical locations
so there is no single point of failure to prevent recovery. Below, the .bitcoind.backupwallet function
is used to write a new wallet.dat file to a backup directory.
// Arguments:
// 1. " d estinatio n " ( st ring ) The destination directo r y or file
9
q ). b itcoin d . b ackupwallet [ " / home / btc / m yback up / ba ckupDir / "]
4.4 Multi-Signature Wallet
Multi-Signature wallet addresses are one of the best known ways to secure crypto-assets. These
are addresses which require a number of private keys to be used together to move funds. The
multiple private keys can be stored across different physical locations and by multiple individuals,
minimising the risk of funds being stolen should a single private key be comprimised. Below, the
.bitcoind.addmultisigaddress function is used to generate a multi-sig address requiring two private
keys to perform a transaction.
// Arguments:
// 1. nr equir ed ( numeric , req uired )
// The number of require d s i gnatures out of the n keys or ad dresses .
// 2. " keys " ( string , requ ired ) A json array of bitcoin addres ses
// or hex - encoded public keys
// [
// " ad dress " ( string ) bitco in add ress or hex - encoded public key
// ... ,
// ]
// 3. " accou nt " ( string , o ptional ) D E P RECATED .
// An accou nt to assign the addres s e s to .
// 4. " addres s_ ty pe " ( string , o ptiona l ) The a ddre ss type to use .
// Opt ions are " legacy " , " p2sh - segwit " , and " be ch32 ".
q ). b itcoin d . getnewaddress [ " MSi g Acc " ;" bec h32 "]
result| "bc1q8j05t0m04lv7gkn2crkeq7g5gq9xn0alk6p5lu"
q ). b itcoin d . getnewaddress [ " MSi g Acc " ;" bec h32 "]
result| "bc1qmaadgvjrqj45u758rc8grfppdaedwshz38l46a"
q ). b itcoin d . getnewaddress [ " MSi g Acc " ;" bec h32 "]
result| "bc1qgkvxclhgf2yw2snh0pw0sf9yutug9pxhjl304z"
q)addressOne:"bc1q8j05t0m04lv7gkn2crkeq7g5gq9xn0alk6p5lu"
q)addressTwo:"bc1qmaadgvjrqj45u758rc8grfppdaedwshz38l46a"
q) addressThree :"bc1qgkvxclhgf2yw2snh0pw0sf9yutug9pxhjl304z"
q) Keys :( addressOne ; a d d r essTwo ; addressThree )
q ). b it co ind . a dd mu ltis ig ad dr ess [2; K ey s ; "multiSig";" b ech 32 " ][ `result]
ad dress |
"bc1qvadv2tzue3nvxg7u2lmfg9mrevrd2jjq7pa7afkscuvjl2j2xnhqcqq4qn"
redeemScript|
"5221030030f8b96f11da696e5d1cbfb13b7bf1055dee22e7eee523179a192446
f6d77121022fd014adef186d4e1a3df09146d9fc0da653fba5d42ae31233aa38
8be9e53fac21027c0a88252ac7b4345b7351e3daccf1965da3ea214fda6fa6ec
10
ceb5c45a5986e453ae"
4.5 Proof of Ownership
One requirement for any custodian provider is to be able to prove that they are in full control
over their clients funds. For Bitcoin, this requires the custodian to have full cryptographic control
over all assets, meaning they are in possession of the private keys associated with the addesses
which hold funds. The core wallet provides a simple and effecive way to provide this proof-of-
ownership through the use of digital signatures. In this case, a challenge message is signed using
the private key associated with a given address which holds funds. The challenge message, signed
message and public address can then be used to validate that the private key used in signing is
valid. If the signature is valid then the signer has control over the funds held on the adddress. In
the example below, a short challenge message containing the text ”Proof of Ownership”, is signed
using the .bitcoind.signmessage function, and the signed message subsequently validated using the
.bitcoind.validatemessage function. Validation can be performed independently.
// Arguments:
// 1. " addre ss " ( string , re q uired )
// The b itcoi n addr ess to use for the priva te key .
// 2. " messa ge " ( string , re q uired )
// The me ss age to cr eat e a s ig natur e of .
// Sign Chall e nge Message with Pr ivate Key
q)walletAddr:"1CzqfiNq6u3aF2CPq9LRKQ6pFJFV5tDVrG"
q) challengeMsg :" Proof of Ow n ership "
q ). b itcoin d . signmessage [ wal l e tAddr ; challengeMsg ]
result| " H0Pz 8 ndn + H F Z NN H U Ha h X Zh f B RP u N i2 9 t JW f b 4X E o os 9 T E3 r i I5 K ... "
error | 0 n
id | 0f
// Arguments:
// 1. " addre ss " ( string , requir ed )
// The bi tcoin addre ss to use for the signature .
// 2. " s i gnature "( string , requir e d ) The sig n ature pro vided
// by the s ign er in base 64 en codi ng ( see s ig nmessage ).
// 3. " messa ge " ( string , requi r ed ) The messag e that was signed .
// Verify Signed M essag e
q) signe d Msg :. b itcoin d . s ignmessage [ walle t A ddr ; challengeMsg ][ `result]
q ). b itcoin d . verifymessage [ walletA d d r ; signed M sg ; challengeMsg ]
result | 1b
error | 0 n
id | 0f
11
5 Receiving and Sending funds securely
5.1 Create a receive address
The first step in receiving funds securely is to generate a new valid bitcoin address using either
an offline hardware wallet, or by running the bitcoin core wallet completely offline and using the
command below, as previously described in Section - Address Generation.
// Of fline wallet
q ). b itcoin d . getnewaddress [ "TestAddr";" bech32 " ]
result | bc1qkmp5q4v8vzkcke8dxryv2qa2uarytx4t4srrgh
Next, import this generated address into the online full node so that ingoing and outgoing funds
can be monitored, see Section - Watch Only Wallet
// Online Full node
q) receiveAddress : "bc1qkmp5q4v8vzkcke8dxryv2qa2uarytx4t4srrgh"
q ). b itcoin d . importaddress [ receiveAddre s s ; " W atc h On ly Ad dre ss " ;0 b ;0 b ]
result|
error |
id | 0
Confirm that the address has been assigned to the correct account using the .bitcoind.getaccount
function.
// Arguments:
// 1. " addre ss " ( string , r equired )
// The bi tcoin address for ac count lookup .
q ). b itcoin d . g etaccount ["bc1qkmp5q4v8vzkcke8dxryv2qa2uarytx4t4srrgh"]
result| " Watch Only Addr ess "
error | 0 n
id | 0f
5.2 Confirming Received Funds
Once the watch-only address has been added to the ”Watch Only Address” account then the
.bitcoind.listaccounts function can be used to confirm the total balance of bitcoin on that account.
The function takes two optional arguments, the first being the minimum number of confirmations
(minconf) a transaction must have in order for its balance to be counted, and the second being
a boolean flag indicating whether to include watch-only addresses in the result. The number of
12
confirmations is a measure of how many blocks deep the transaction is on the blockchain, the higher
the number the more confident you can be in the transactions finalisation. Most merchants opt for
6 confirmations to be received before deeming funds confirmed. In the example below, we can see
that for an incoming transaction with just one confirmation in real-time the listaccounts function
shows a positive balance for a minconf of 1, but a zero balance for a minconf value of 6.
// Arguments:
// 1. mincon f ( numeric , optional , d efa ult =1) Only includ e
// transacti o n s with at least this many confirmations
// 2. in cl ud e_ watc ho nl y ( bool , op tiona l , d efau lt = fa lse )
// Inclu de ba lances in watch - only ad dress es ( see 'importaddress')
q ). b it co in d . l i st ac c ou nt s [ 1; 1 b ][ `result]
Watch Only Address | 0.010712 7 3
q ). b it co in d . l i st ac c ou nt s [ 6; 1 b ][ `result]
Watch Only Address | 0 f
Once funds have been confirmed the .bitcoind.listunspent function can be used to display the
amount of unspent funds held on a given address together with some important transactional
information such as the transaction identifier, txid. The function takes 3 arguments, the minimum
and maximum number of confirmations and the list of addresses to filter. Below the spendable flag
returns a value of 0b, which indicates the wallet does not have the private key to spend the output,
because it is stored safely on the offline computer.
// Arguments:
// 1. mincon f ( numeric , r equir ed ) The minimum c onfirmations to filter
// 2. maxcon f ( numeric , r equir ed ) The maximum c onfirmations to filter
// 3. addr e sses ( stri ng ) A json array of bi tcoin a ddresses to filt er
// [
// " address " ( st ring ) bitco in add ress
// ,...
// ]
q) flip . bit c oind . listuns p e n t [1 ;1000 00;()] [ `result]
txid | "ee9abf639bf459aea85fdf353a362b8f99
db1d6c048fe55b69935b89b4c490fa"
vout | 0
ad dress | "bc1qkmp5q4v8vzkcke8dxryv2qa2uarytx4t4srrgh"
ac count | " Watch Only Address "
scriptPubKey | " 0014 b6c3 4 05 58 76 0a d8b 64 ed 30 c8 c50 3a ae 74 64 59a ab "
amount | 0.01071273
confirmations| 1
spendable | 0
13
solvable | 0
safe | 1
5.3 Create Transaction
Bitcoin transactions involve inputs and outputs, inputs are bitcoins you can combine together to
use in a transaction (like the coins in your pocket), and outputs are the amounts of bitcoin sent
to new addresses as part of the transaction. In the example below, a transaction is created to
spend the funds associated with the watch-only address in the previous section. To create a new
transaction, we use the .bitcoind.createrawtransaction function which takes as a first argument a
dictionary containing the transaction ID (txid) and vout of the input to the transaction. This
information was already presented in the previous section, and is contained in the output of the
.bitcoind.listunspent function. The second argument, the outputs variable, is again a dictionary
containing as key the addresses to send bitcoin to and the associated amount. In this case, we have
one input and one output, so we are moving bitcoin from one address to another. The final two
arguments are optional and correspond to the locktime and replacable values which are out of the
scope of this document.
// Arguments:
// 1. " i npu ts " ( array , r equir ed ) A js on ar ray of jso n obj ects
// [
// {
// " t xi d " :" id " , ( stri ng , r eq ui red ) The t ran sac tio n id
// " v ou t ": n , ( num eric , r eq ui red ) The o utpu t n um ber
// " seq uence ": n ( numeric , optio nal ) The sequenc e number
// }
// ,...
// ]
// 2. " outpu ts " ( object , req u ired ) a json object with outp uts
// {
// " ad dress ": x . xxx , ( nu meric or string , requi red )
// The key is the b itcoi n address ,
// the nu meric value is the BTC amount
// " data ": " hex " ( string , r equire d ) The key is " data " ,
// the value is hex encode d data
// ,...
// }
// 3. lo ckti me ( numeric , optional , defau lt =0) Raw lockti me .
// Non -0 value also locktime - activate s inputs
// 4. re placeable ( boolean , optional , defau lt = false )
// Marks this transacti o n as BIP125 repl a c e a b le .
// Allo ws this t r a n s a ction to be replace d by a transac t i o n
// with higher fees . If provided , it is an error if explic it
// s equenc e numbers are in c o m p a t i b l e .
14
q)t:" ee9 a b f6 3 9b f 45 9 ae a 85 f df 3 5 3a 3 62 b 8f 9 9d b 1d 6 c0 4 8f e 55 b 6 99 3 5b 8 9b 4 c4 9 0f a "
q)sendToAddr:`bc1qzsg3qkd9r3986q96h7kgqhhfrps9hpa5a2yn8j
q) inputs : enlis t `txid `vou t !( t ;0)
q) outputs :( enlist send T o Addr )! enlist 0. 01071
q ). bit coind . c r e a t eraw t r a nsac t i o n [ inputs ; out puts ;0;1 b ]
result|"0200000001fa90c4b4895b93695be58f046c1ddb998f2b363a35df5fa8ae
59f49b63bf9aee0000000000fdffffff0198571000000000001600141411
1059 a51c4 a 7 d0 0 b ab f ac 8 0 5e e 9 18 6 0 5b 8 7 b4 0 00 0 0 00 0 "
error | 0 n
id | 0f
The above step of creating a transaction can be performed on either and online or offline
computer. The output result, however, needs to trnsferred to the offline wallet for private key
signing, described in detail below.
5.4 Sign Transaction
Signing a transaction is the next important step in which the private keys associated with the
spending addresses are required. The function which can be used to perform the signing action is
called .bitcoind.signrawtransaction, and its argument list is given below. Note, this step should be
performed on an offline computer for increased security. Below, the scriptPubKey value is again
taken from the output of the function .bitcoind.listunspent.
// Arguments:
// 1. " h exstring " ( string , r equired ) The transactio n hex string
// 2. " p revtx s " ( string , opt i onal ) An json array of pr evious
// dep e ndent transacti o n o utput s
// [ ( json array of json objects , or 'null')
// {
// " t xi d " :" id " , ( st ring , r equi re d ) T he trans ac tio n id
// " v ou t ": n , ( nume ri c , r eq uire d ) The ou tp ut nu mbe r
// " s cr iptPubKey ": " hex " , ( string , r equir ed ) s cri pt key
// " r ed eemScript ": " hex " , ( string , r equir ed ) r ede em scri pt
// " amo unt ": value ( numeric , req uired ) The amou nt spent
// }
// ,...
// ]
// 3. " p rivkey s " ( string , optio nal ) A json array of base58 - enco ded
// p rivat e keys for signi ng
// [ ( json array of strings , or 'null'if none provid e d )
// " priv a t ekey " ( string ) pr ivate key in base58 - en c oding
// ,...
// ]
// 4. " s ig hashtype " ( string , opt ional , defau lt = ALL )
15
// The sign ature hash type . Must be one of
// " ALL "
// " NONE "
// " SI NGLE "
// " ALL | ANYONECANPA Y "
// " NONE | ANYONECA NPAY "
// " SINGLE | ANYONECANPAY "
q)hexstring:"0200000001fa90c4b4895b93695be58f046c1ddb998f2b363a35df
5fa8ae59f49b63bf9aee0000000000fdffffff0198571000000000
0016001414111 0 5 9 a 5 1 c 4a 7 d0 0 b ab f a c8 0 5 ee 9 18 6 0 5b 8 7 b4 0 0 00 0 00 0 "
q)t:" ee9 a b f6 3 9b f 45 9 ae a 85 f df 3 5 3a 3 62 b 8f 9 9d b 1d 6 c0 4 8f e 55 b 6 99 3 5b 8 9b 4 c4 9 0f a "
q) scriptPubKey :" 0014 b6c 3 40 55 87 60 ad 8b 6 4e d3 0c 8c 50 3 aa e7 46 45 9a a b "
q ) p re vt xs Va lu es :( t ;0 f ; s cr ip tP ub Ke y ; 0. 01 07 12 73)
q) prev txs : en list `txid `vout `scriptPubKey `amount!prevtxsValues
q) priv keys : en list " P riv ate Key Goes Here "
q ). b itcoin d . signraw t r a n s a ction [ h exstring ; p revtx s ; privke ys ]
result| `hex `complete!(" 0 20 000000001 01 fa 9 .. . " ;1 b )
error | 0 n
id | 0f
Note that the previous two steps of creating a transaction and signing a transactions can also
be performed on the Trezor hardware wallet using the ”Sign without Sending” option, and will
produce a similar hex value as shown in the example above.
5.5 Broadcast Transaction
The output hex string from the signing action can now be broadcast to the bitcoin network from
the online full node by using the .bitcoind.sendrawtransaction function. If successful, the result
value contains a transaction ID which can be used to track the state of the transaction on the
blockchain.
// Arguments:
// 1. " h exstring " ( string , req u ired )
// The hex st ring of the raw transaction )
// 2. allowhighfees ( boolean , optional , def ault = fal se )
// Allow high fees
q ). bitcoi n d . send r a w t r a nsac t i o n [ " 0 20 00 00 00 00101 fa9 .. . " ;1 b ][ `result]
"78889f97c5d105b5b5a13807d10438bab700db08cb88581a1f8bb3c10ad368e0"
16
5.6 Sending from a hot wallet
In the case where the private keys associated with funds are already present in the wallet of the
online running node, then it is possible to perform a more straight forward transaction using
the .bitcoind.sendtoadddress function. This performs the create transaction, sign transaction and
broadcast transaction in one convenient step. At a minimum, this function needs only the receving
address and the amount to send. Below are shown the additional optional arguments.
// Arguments:
// 1. " addre ss " ( string , r equired ) The bit coin addres s to send to .
// 2. " amount " ( num eric or string , req u ired ) The a moun t in BTC to
// send . eg 0.1
// 3. " comme nt " ( string , o ptional ) A co mment used to store what the
// transaction is for .
// This is not part of the tran saction , just kept in your wallet .
// 4. " c o mment_to " ( string , option a l ) A comme nt to st ore the name of
// the person or organization to which you 're s endin g the transa c t i o n .
// This is not part of the tran saction , just kept in your wallet .
// 5. subtr actf eef rom amo unt ( boolean , optional , def ault = false ) The
// fee will be deduc t ed from the amount being sent . The reci p ient
// will receive less bit coins than you enter in the amou nt field .
// 6. r e p l aceable ( boolean , optio n al ) Allow this transac t i o n to be
// r eplaced by a transacti o n with higher fees via BIP 125
// 7. co nf_targe t ( numeric , opt ional ) Confirmation target ( blocks )
// 8. " estimate_mode " ( string , optional , def ault = UNSET ) The fee
// e st im ate mode , m us t be on e of :
// " U NS ET " ," E CO NO MICAL " ," C ON SE RV AT IV E "
q)ToAddr:bc1q9sldykvtnt2grrq44qyfaxe8p6lwmrewjk7yqj
q ). b itcoin d . sendtoaddress [ To Addr ;0.01070][ `result]
"67e5a14dcac0d7243a6c21b25b15f9520d28864dbca337d3e97138d3df8e393e"
References
[1] Nakamoto, Satoshi, Bitcoin: A Peer-to-Peer Electronic Cash System
https://bitcoin.org/bitcoin.pdf
[2] Poon, Joseph and Dryja, Thaddeus The Bitcoin Lightning Network: Scalable Off-Chain In-
stant Payments
https://lightning.network/lightning-network-paper.pdf
17

Navigation menu