From bf12843d24ce261b9b307daef3a89bcbdd013114 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 18 Jun 2020 09:03:02 +1000 Subject: [PATCH 01/13] Fixed existing sections of Accessing_Bitcoind_with_NodeJS --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 49 ++++++++++++++++++-------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index e536aab..80d01fc 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -7,35 +7,40 @@ BCRPC is built on node.js. Thus, you'll first need to install the `node.js` and `npm` (node package manager) packages for your system. If you're using a Ubuntu machine, you can run the following commands to get a new version of `node.js` (as opposed to the horribly out-of-date version in the Ubuntu package system). -``` -curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - -sudo apt-get install -y nodejs -sudo apt-get install mocha -g -``` -### Set Up BCRPC -Create a new node.js project and install BCRPC via NPM. ``` -$ mkdir myproject -$ cd myproject -$ npm init -[...] -$ npm install --save bcrpc +curl -sL https://deb.nodesource.com/setup_14.x | sudo bash - +sudo apt-get install -y nodejs +sudo npm install mocha -g ``` + ### Test BCRPC -To test the BCRPC package, you must first set environmental variables for your rpcuser and rpcpassword. As noted in [§12.1: Accessing Bitcoind with Curl](12_1_Accessing_Bitcoind_with_Curl.md), these come from `~/.bitcoin/bitcoin.conf`. +Clone the BCRPC package from GitHub and install its dependencies. + +``` +$ git clone https://github.com/dgarage/bcrpc.git +$ cd bcrpc +$ npm install +``` + +To test the BCRPC package, you must first set environmental variables for your rpcuser and rpcpassword. As noted in [§12.1: Accessing Bitcoind with Curl](12_1_Accessing_Bitcoind_with_Curl.md), these come from `~/.bitcoin/bitcoin.conf`. You must also set the RPC port to 18332 which should be correct for the standard testnet setup described in these documents. + ``` $ export BITCOIND_USER=bitcoinrpc $ export BITCOIND_PASS=d8340efbcd34e312044c8431c59c792c +$ export BITCOIND_PORT=18332 ``` + > **WARNING:** Obviously, you'd never put set your password in an environmental variable in a production environment. +> **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup. You can now verify everything is working correctly: + ``` $ npm test -> bcrpc@0.0.5 test /home/user1/bcrpc-master +> bcrpc@0.2.2 test /home/user1/bcrpc > mocha tests.js BitcoinD @@ -46,7 +51,21 @@ $ npm test 2 passing (36ms) ``` -Congratulations, you now have a Bitcoin-ready RPC wrapper for node.js. + +Congratulations, you now have a Bitcoin-ready RPC wrapper for Node.js working with your Bitcoin setup. + +### Set Up BCRPC + +Leave the BCRPC directory and create a new Node.js project with BCRPC installed via npm. + +``` +$ cd .. +$ mkdir myproject +$ cd myproject +$ npm init + [continue with default options] +$ npm install bcrpc +``` ## Manipulate Your Wallet From 0ddac5f54b7e6f255dff81375649fe3391e98843 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 18 Jun 2020 09:05:57 +1000 Subject: [PATCH 02/13] Fixed typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06cc30f..bd6f387 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ _This section is currently a messy set of older writings which are being reorgan * 18.0: Talking to Bitcoind with Other Languages * [18.1: Accessing Bitcoind with Go] * [18.2: Accessing Bitcoind with Java](18_2_Accessing_Bitcoind_with_Java.md) — Needs Rewrite + Editing - * [18.3: Accessing Bitcoind with_Node_JS](18_3_Accessing_Bitcoind_with_NodeJS.md) — Needs Rewrite + Editing + * [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) — Needs Rewrite + Editing * [18.4: Accessing Bitcoind with Python] * [18.5: Accessing Bitcoind with Rust] * [18.6: Accessing Bitcoind with Swift] From a3160733952e984854f7d25b471fba48b54d7c78 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 10:33:16 +1000 Subject: [PATCH 03/13] Node.js --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 186 ++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 5 deletions(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 80d01fc..47a8a6c 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -67,14 +67,190 @@ $ npm init $ npm install bcrpc ``` -## Manipulate Your Wallet +In this ```myproject``` directory, create a file called ```server.js``` in which the JavaScript code can be executed. Enter the following at the top of the file to connect to your Bitcoin node: -### Look Up Addresses +``` +const RpcAgent = require('bcrpc'); +agent = new RpcAgent({port: 18332, user: 'bitcoinrpc', pass: 'd8340efbcd34e312044c8431c59c792c'}); +``` -### Look Up Funds +Now we can start writing programs in JavaScript that access Bitcoind. You can use the same RPC commands you would usually use via ```bitcoin-cli```, except they need to be in camelCase. For example, ```getblockhash``` would be ```getBlockHash``` instead. + +### Print the Newest Block + +To print the newest block number along with its hash, we can first call ```getBlockCount```, print it, then pass the block number to ```getBlockHash``` and then print the latest hash. Add this code to ```server.js```: + +``` +agent.getBlockCount(function (err, blockCount) { + if (err) + throw Error(JSON.stringify(err)); + console.log(blockCount.result); + agent.getBlockHash(blockCount.result, function (err, hash) { + if (err) + throw Error(JSON.stringify(err)); + console.log(hash.result); + }) +}); +``` + +You can run it with ```$ node server.js```. You should get an output similar to this: + +``` +1773373 +0000000000000083d29c524d4cfc257adfab8fa9b6f0d207d1d0f1b63e1de11e +``` + +## Look Up Your Wallet + +You can also lookup your wallet and view your balance, transaction count et cetera: + +``` +agent.getWalletInfo(function (err, walletInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(walletInfo.result); +}); +``` + +When you run it, you should get an output similar to this: + +``` +{ + walletname: '', + walletversion: 169900, + balance: 0.0011, + unconfirmed_balance: 0, + immature_balance: 0, + txcount: 2, + keypoololdest: 1591844503, + keypoolsize: 999, + keypoolsize_hd_internal: 1000, + paytxfee: 0, + hdseedid: '6b9ccb7d96c45a3ca407a3f3b0e9b42501f05c49', + private_keys_enabled: true +} +``` + +Instead of printing all the details associated with your wallet, you can print specific information such as your balance. Since a JSON object is being accessed, this can be done by changing the line ```console.log(walletInfo.result);``` to ```console.log(walletInfo.result.balance);```: + +``` +0.0011 +``` ### Create an Address -## Create a Transaction - +We can pass additional arguments to RPC commands as well. Here is an example for generating a new legacy address, with the ```-addresstype``` flag. + +``` +agent.getNewAddress('-addresstype', 'legacy', function (err, newAddress) { + if (err) + throw Error(JSON.stringify(err)); + console.log(newAddress.result); +}); +``` + +Output: +``` +mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ +``` + +### List transactions + +We can list our previous transactions and view information about transactions such as amount and number of confirmations: + +``` +agent.listTransactions(function (err, transactions) { + if (err) + throw Error(JSON.stringify(err)); + console.log(transactions.result); +}); +``` + +We can also examine a transaction based on its txid: + +``` +agent.getTransaction('1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', function (err, transaction) { + if (err) + throw Error(JSON.stringify(err)); + console.log(transaction.result); +}); +``` + +You should get an output similar to this: + +``` +{ + amount: 0.001, + confirmations: 4776, + blockhash: '000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a', + blockindex: 117, + blocktime: 1591857418, + txid: '1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df', + walletconflicts: [], + time: 1591857343, + timereceived: 1591857343, + 'bip125-replaceable': 'no', + details: [ + { + address: 'mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', + category: 'receive', + amount: 0.001, + label: '', + vout: 0 + } + ], + hex: '02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00' +} +``` + +### Get address balance + +A useful function when accepting Bitcoin is checking the balance of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with ```getNewAddress``` function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +By default this functions checks the transactions that have been confirmed once, however we can increase this to a higher number such as 6: + +``` +agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', 6, function (err, addressInfo) { + if (err) + throw Error(JSON.stringify(err)); + console.log(addressInfo.result); +}); +``` + +Output: + +``` +0.0011 +``` + +## Sending coins + +We can send coins to an address using the ```sendToAddress``` function: + +``` +agent.sendToAddress('n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi', 0.00001, function(err, txid) { + if (err) + throw Error(JSON.stringify(err)); + console.log(txid.result); +}); +``` + +This should print the txid of the transaction: + +``` +6172d60d154cd4bbb5b6adeaffa191866f3904dd3f525c7a079154aea906b723 +``` + +We can also use the ```getTransaction``` function to view how many confirmations it has, what fee we paid, et cetera. + ## Summary: Accessing Bitcoind with Node + +With BCRPC we can do all the commands available through ```bitcoin-cli```, in JavaScript. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins. From 1f7436fc13ff3288b115d5c51ba2746a727d35c9 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 10:34:17 +1000 Subject: [PATCH 04/13] Node.js --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 47a8a6c..0926ce4 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -1,7 +1,5 @@ # 18.3: Accessing Bitcoind with NodeJS -> **NOTE:** This is a draft in progress, so that I can get some feedback from early reviewers. It is not yet ready for learning. - ## Set Up Node.js BCRPC is built on node.js. Thus, you'll first need to install the `node.js` and `npm` (node package manager) packages for your system. From b49fc22895dcac749f49e9222fe7914ff6e168e3 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 14:12:50 +1000 Subject: [PATCH 05/13] Go --- 18_1_Accessing_Bitcoind_with_Go.md | 337 +++++++++++++++++++++++++ 18_3_Accessing_Bitcoind_with_NodeJS.md | 4 +- README.md | 4 +- 3 files changed, 341 insertions(+), 4 deletions(-) create mode 100644 18_1_Accessing_Bitcoind_with_Go.md diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md new file mode 100644 index 0000000..0ab73e1 --- /dev/null +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -0,0 +1,337 @@ +# 18.1: Accessing Bitcoind with NodeJS + +## Set up Go + +First, install curl if you haven't already: + +``` +$ sudo apt install curl +``` + +Then, look at the [Go downloads page](https://golang.org/dl/) and get the link for the latest download: + +``` +$ curl -O https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz +``` + +Once it finishes downloading, compare the hash of the download to the hash on the [Go downloads page](https://golang.org/dl/): + +``` +$ sha256sum go1.14.4.linux-amd64.tar.gz +aed845e4185a0b2a3c3d5e1d0a35491702c55889192bb9c30e67a3de6849c067 /home/user1/go1.14.4.linux-amd64.tar.gz +``` + +The hashes should match. Now we can extract the tarball and install Go on our system: + +``` +$ tar xvf go1.12.5.linux-amd64.tar.gz +$ sudo chown -R root:root ./go +$ sudo mv go /usr/local +``` + +Now we need to create a Go path to specify our environment. Open the ```~/.profile``` file with an editor of your choice and add the following to the end of it: + +``` +export GOPATH=$HOME/work +export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin +``` + +Then, refresh your profile: + +``` +$ source ~/.profile +``` + +Lastly, create the directory for your Go workspace: + +``` +$ mkdir $HOME/work +``` + +## Setup btcd rpcclient + +We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. We can use ```go get``` to download it: + +``` +$ go get github.com/btcsuite/btcd/rpcclient +``` + +To test that it works, navigate to the directory with the Bitcoin core examples: + +``` +$ cd $GOPATH/src/github.com/btcsuite/btcd/rpcclient/examples/bitcoincorehttp +``` + +Modify the ```main.go``` file and enter the details associated with your Bitcoin core setup: + +``` + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "d8340efbcd34e312044c8431c59c792c", +``` + +Now run: + +``` +$ go run main.go +``` + +You should see the block count printed: + +``` +2020/06/24 20:41:01 Block count: 1773552 +``` + +### Print the latest block + +Leave the btcd directory and create a new Go project: + +``` +$ mkdir -p ~/work/src/myproject/bitcoin +$ cd ~/work/src/myproject/bitcoin +``` + +In this directory, create a file called ```main.go``` and enter the following in it: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatal(err) + } + blockHash, err := client.GetBlockHash(blockCount) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%d\n", blockCount) + fmt.Printf("%s\n", blockHash.String()) +} +``` + +Make sure to change your username and password to those from your ```~/.bitcoin/bitcoin.conf``` file. When you run this: + +``` +$ go run main.go +1773561 +00000000000000346bab4126f418a5820692c9a7de7ef79717bebfccebacad61 +``` + +The latest block number along with its hash should be printed out. + +### Getting your wallet balance + +Since the btcd rpcclient is quite limited, we can't make a use the ```getwalletinfo``` functino, however we can get the balance of our wallet: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + wallet, err := client.GetBalance("*") + if err != nil { + log.Fatal(err) + } + fmt.Println(wallet) +} +``` + +You should get an output similar to this: + +``` +0.000689 BTC +``` + +### Get amount received by an address + +We can retrieve the amount of Bitcoin received by a specific address: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", defaultNet) + if err != nil { + log.Fatal(err) + } + wallet, err := client.GetReceivedByAddress(addr) + + fmt.Println(wallet) +} +``` + +The defaultNet variable is used to specify whether our Bitcoin node is on testnet or on mainnet. + +### Sending Bitcoin to an address + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + defaultNet := &chaincfg.TestNet3Params + addr, err := btcutil.DecodeAddress("n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi", defaultNet) + if err != nil { + log.Fatal(err) + } + + sent, err := client.SendToAddress(addr, btcutil.Amount(1e4)) + if err != nil { + log.Fatal(err) + } + fmt.Println(sent) +} +``` + +This outputs the txid of the transaction. + +### Lookup a transaction + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg/chainhash" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + chash, err := chainhash.NewHashFromStr("1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df") + if err != nil { + log.Fatal(err) + } + transactions, err := client.GetTransaction(chash) + if err != nil { + log.Fatal(err) + } + fmt.Println(transactions) +} +``` + +This prints out the details associated with a transaction, such as its amount and how many times it has been confirmed: + +``` +{ + "amount": 0.00100000, + "confirmations": 4817, + "blockhash": "000000006628870b0a8a66abea9cf0d4e815c491f079e3fa9e658a87b5dc863a", + "blockindex": 117, + "blocktime": 1591857418, + "txid": "1661ce322c128e053b8ea8fcc22d17df680d2052983980e2281d692b9b4ab7df", + "walletconflicts": [ + ], + "time": 1591857343, + "timereceived": 1591857343, + "bip125-replaceable": "no", + "details": [ + { + "address": "mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha", + "category": "receive", + "amount": 0.00100000, + "label": "", + "vout": 0 + } + ], + "hex": "02000000000101e9e8c3bd057d54e73baadc60c166860163b0e7aa60cab33a03e89fb44321f8d5010000001716001435c2aa3fc09ea53c3e23925c5b2e93b9119b2568feffffff02a0860100000000001976a914600c8c6a4abb0a502ea4de01681fe4fa1ca7800688ac65ec1c000000000017a91425b920efb2fde1a0277d3df11d0fd7249e17cf8587024730440220403a863d312946aae3f3ef0a57206197bc67f71536fb5f4b9ca71a7e226b6dc50220329646cf786cfef79d60de3ef54f702ab1073694022f0618731902d926918c3e012103e6feac9d7a8ad1ac6b36fb4c91c1c9f7fff1e7f63f0340e5253a0e4478b7b13f41fd1a00" +} +``` + +## Summary: Accessing Bitcoind with Node + +Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. \ No newline at end of file diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 0926ce4..a133071 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -201,9 +201,9 @@ You should get an output similar to this: } ``` -### Get address balance +### Get Amount Received by an Address -A useful function when accepting Bitcoin is checking the balance of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with ```getNewAddress``` function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received: +A useful function when accepting Bitcoin is checking the received Bitcoin of a specific address in your wallet. For example, if you were running an online store accepting Bitcoin, for each payment from a customer, you would generate a new address (as we did with ```getNewAddress``` function), show that address to the customer, then check the balance of the address after some time, to make sure the correct amount has been received: ``` agent.getReceivedByAddress('mpGpCMX6SuUimDZKiVViuhd7EGyVxkNnha', function (err, addressInfo) { diff --git a/README.md b/README.md index bd6f387..2b7f575 100644 --- a/README.md +++ b/README.md @@ -104,9 +104,9 @@ _This section is currently a messy set of older writings which are being reorgan * 17.4: Integrating Libwally and Scripts * 17.0: Talking to Lightningd with C * 18.0: Talking to Bitcoind with Other Languages - * [18.1: Accessing Bitcoind with Go] + * [18.1: Accessing Bitcoind with Go](18_1_Accessing_Bitcoind_with_Go.md) * [18.2: Accessing Bitcoind with Java](18_2_Accessing_Bitcoind_with_Java.md) — Needs Rewrite + Editing - * [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) — Needs Rewrite + Editing + * [18.3: Accessing Bitcoind with Node JS](18_3_Accessing_Bitcoind_with_NodeJS.md) * [18.4: Accessing Bitcoind with Python] * [18.5: Accessing Bitcoind with Rust] * [18.6: Accessing Bitcoind with Swift] From 3c14e11745dd85031d656d9ea0d17a38827c4902 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Thu, 25 Jun 2020 14:15:56 +1000 Subject: [PATCH 06/13] go --- 18_1_Accessing_Bitcoind_with_Go.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 0ab73e1..d4341ae 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -1,4 +1,4 @@ -# 18.1: Accessing Bitcoind with NodeJS +# 18.1: Accessing Bitcoind with Go ## Set up Go @@ -334,4 +334,4 @@ This prints out the details associated with a transaction, such as its amount an ## Summary: Accessing Bitcoind with Node -Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. \ No newline at end of file +Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. From c8b92bc287ac128ea7bab911f7689c7c7615f2b6 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 14:57:09 +1000 Subject: [PATCH 07/13] revision --- 18_1_Accessing_Bitcoind_with_Go.md | 87 +++++++++++++++++++++++--- 18_3_Accessing_Bitcoind_with_NodeJS.md | 2 +- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index d4341ae..4dce43c 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -50,7 +50,7 @@ $ mkdir $HOME/work ## Setup btcd rpcclient -We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. We can use ```go get``` to download it: +We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. Although btcd was originally designed to work with the btcd Bitcoin full node, it also works with Bitcoin core. It has some quirks which we will be looking at. We can use ```go get``` to download it: ``` $ go get github.com/btcsuite/btcd/rpcclient @@ -69,6 +69,7 @@ Modify the ```main.go``` file and enter the details associated with your Bitcoin User: "bitcoinrpc", Pass: "d8340efbcd34e312044c8431c59c792c", ``` +> **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup. Now run: @@ -130,7 +131,15 @@ func main() { } ``` -Make sure to change your username and password to those from your ```~/.bitcoin/bitcoin.conf``` file. When you run this: +Make sure to change your username and password to those from your ```~/.bitcoin/bitcoin.conf``` file. + +The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. For example, ```bitcoin-cli getblockcount``` is ```client.GetBlockCount``` in Go. The ```connCfg``` parameters allow you to choose the Bitcoin RPC port, username, password and whether you are on testnet or mainnet. Using ```rpcclient.New(connCfg, nil)``` we configure ```client``` to connect to our Bitcoin node. + +The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt" and "github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. + +A quirk with hashes in rpcclient is that they will typically print in a different encoding if you were to print it normally with ```blockHash```. In order to print them as a string, we need to use ```blockHash.String()```. + +We can run Go code with ```go run main.go```: ``` $ go run main.go @@ -142,7 +151,7 @@ The latest block number along with its hash should be printed out. ### Getting your wallet balance -Since the btcd rpcclient is quite limited, we can't make a use the ```getwalletinfo``` functino, however we can get the balance of our wallet: +Since the btcd rpcclient has some limits, we can't make a use of the ```getwalletinfo``` function, however we can get the balance of our wallet: ``` package main @@ -171,6 +180,7 @@ func main() { if err != nil { log.Fatal(err) } + fmt.Println(wallet) } ``` @@ -181,6 +191,50 @@ You should get an output similar to this: 0.000689 BTC ``` +```client.GetBalance("*")``` requires the ```"*"``` input, due to a quirk with btcd. The asterisk signifies that we want to get the balance of all our wallets. + +### Generate an address + +We can generate addresses, but we can't specify the address type: + +``` +package main + +import ( + "log" + "fmt" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/chaincfg" +) + +func main() { + connCfg := &rpcclient.ConnConfig{ + Host: "localhost:18332", + User: "bitcoinrpc", + Pass: "431451790e3eee1913115b9dd2fbf0ac", + HTTPPostMode: true, + DisableTLS: true, + Params: chaincfg.TestNet3Params.Name, + } + client, err := rpcclient.New(connCfg, nil) + if err != nil { + log.Fatal(err) + } + defer client.Shutdown() + + address, err := client.GetNewAddress("") + if err != nil { + log.Fatal(err) + } + fmt.Println(address) +} +``` +> **MAINNET VS TESTNET:** ```Params: chaincfg.TestNet3Params.Name,``` should be ```Params: chaincfg.MainNetParams.Name,``` on mainnet. + +You may notice that the ```connCfg``` clause is different in this example. ```Params: chaincfg.TestNet3Params.Name,``` is added here, so that the rpcclient knows that we are dealing with testnet addresses. You would change ```chaincfg.TestNet3Params.Name``` to ```chaincfg.MainNetParams.Name``` if you were on mainnet. This specification is only required during address generation, which is why I only kept it in this example. You can include this in other examples as well, but it isn't necessary. Make sure to import ```"github.com/btcsuite/btcd/chaincfg"``` if you are using it. + +A quirk with ```client.GetNewAddress("")``` is that an empty string needs to be included for it to work. + ### Get amount received by an address We can retrieve the amount of Bitcoin received by a specific address: @@ -216,12 +270,22 @@ func main() { log.Fatal(err) } wallet, err := client.GetReceivedByAddress(addr) + if err != nil { + log.Fatal(err) + } fmt.Println(wallet) } ``` +> **MAINNET VS TESTNET:** ```&chaincfg.TestNet3Params``` should be ```&chaincfg.TestNet3Params``` on mainnet. -The defaultNet variable is used to specify whether our Bitcoin node is on testnet or on mainnet. +You should get an output similar to this: + +``` +0.000089 BTC +``` + +The defaultNet variable is used to specify whether our Bitcoin node is on testnet or on mainnet. This example requires us to import the ```"github.com/btcsuite/btcutil"``` and ```"github.com/btcsuite/btcd/chaincfg"``` libraries. ```btcutil``` allows for a Bitcoin address to be decoded in a way that the rpcclient can understand. This is necessary when working with addresses in rpcclient. ```chaincfg``` is used to configure our chain as the Testnet chain. This is necessary for address decoding since the addresses used on Mainnet and Testnet are different. ### Sending Bitcoin to an address @@ -255,16 +319,20 @@ func main() { if err != nil { log.Fatal(err) } - sent, err := client.SendToAddress(addr, btcutil.Amount(1e4)) if err != nil { log.Fatal(err) } + fmt.Println(sent) } ``` -This outputs the txid of the transaction. +After the transaction is sent, the txid of the transaction is outputted: + +``` +9aa4cd6559e0d69059eae142c35bfe78b71a8084e1fcc2c74e2a9675e9e7489d +``` ### Lookup a transaction @@ -300,6 +368,7 @@ func main() { if err != nil { log.Fatal(err) } + fmt.Println(transactions) } ``` @@ -332,6 +401,8 @@ This prints out the details associated with a transaction, such as its amount an } ``` -## Summary: Accessing Bitcoind with Node +```"github.com/btcsuite/btcd/chaincfg/chainhash"``` is imported in order to allow hashes to be stored in the Go code. ```chainhash.NewHashFromStr("hash")``` converts a hash in a string, to a format that works with rpcclient. -Although the btcd rpcclient is quite limited, we can still perform a lot of the main rpc commands in Go. +## Summary: Accessing Bitcoind with Go + +Although the btcd rpcclient has some limits, we can still perform the main rpc commands in Go. The documentation for rpcclient is available on [Godoc](https://godoc.org/github.com/btcsuite/btcd/rpcclient). If the documentation doesn't have what your looking for, have a look at the [btcd repository](https://github.com/btcsuite/btcd). It is generally well documented and easy to read. Based on these examples you should be able to incorporate Bitcoin in a Go project and do things like sending and receiving coins. \ No newline at end of file diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index a133071..71138a2 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -251,4 +251,4 @@ We can also use the ```getTransaction``` function to view how many confirmations ## Summary: Accessing Bitcoind with Node -With BCRPC we can do all the commands available through ```bitcoin-cli```, in JavaScript. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins. +With BCRPC we can do all the commands available through ```bitcoin-cli```, in JavaScript. The [BCRPC README](https://github.com/dgarage/bcrpc) has some examples which use promises (the examples in this document use callbacks). The [JavaScript behind it](https://github.com/dgarage/bcrpc/blob/master/index.js) is short and readable. Based on these examples you should be able to incorporate Bitcoin in a Node.js project and do things like sending and receiving coins. From f6b5fac2f8dcdc49ca2ba767da18f0ee64ec482d Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:05:35 +1000 Subject: [PATCH 08/13] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 2 +- 18_3_Accessing_Bitcoind_with_NodeJS.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 4dce43c..8d6d2ee 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -50,7 +50,7 @@ $ mkdir $HOME/work ## Setup btcd rpcclient -We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. Although btcd was originally designed to work with the btcd Bitcoin full node, it also works with Bitcoin core. It has some quirks which we will be looking at. We can use ```go get``` to download it: +We will be using the rpcclient that comes with btcd, a Bitcoin implementation written in Go. Although rpcclient was originally designed to work with the btcd Bitcoin full node, it also works with Bitcoin core. It has some quirks which we will be looking at. We can use ```go get``` to download it: ``` $ go get github.com/btcsuite/btcd/rpcclient diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 71138a2..7f4bd11 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -31,6 +31,7 @@ $ export BITCOIND_PORT=18332 ``` > **WARNING:** Obviously, you'd never put set your password in an environmental variable in a production environment. + > **MAINNET VS TESTNET:** The port would be 8332 for a mainnet setup. You can now verify everything is working correctly: @@ -98,6 +99,17 @@ You can run it with ```$ node server.js```. You should get an output similar to 0000000000000083d29c524d4cfc257adfab8fa9b6f0d207d1d0f1b63e1de11e ``` +The BCRPC functions can accept inputs. For example, ```getBlockHash``` takes ```blockCount.result``` as an input. The result of the BCRPC functions is a JSON object containing information about any errors and the id of the request. When accessing our result, we add ```.result``` to the end of it to specify that we are interested in the actual result, not information about errors. This is what output of the above example would look like if we replaced ```console.log(blockCount.result);``` and ```console.log(hash.result);``` with ```console.log(blockCount);``` and ```console.log(hash);```, respectively: + +``` +{ result: 1774686, error: null, id: null } +{ + result: '00000000000000d980c495a2b7addf09bb0a9c78b5b199c8e965ee54753fa5da', + error: null, + id: null +} +``` + ## Look Up Your Wallet You can also lookup your wallet and view your balance, transaction count et cetera: From 241d4d78c840cc19ea5b3eb2e097be9f1b2fa351 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:09:08 +1000 Subject: [PATCH 09/13] updated --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 7f4bd11..196bf5e 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -164,6 +164,15 @@ Output: mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ ``` +This example shows how we can use the same flags as ```bitcoin-cli``` in BCRPC. The example above would look like this from the command line: + +``` +$ bitcoin-cli getnewaddress -addresstype legacy +mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ +``` + +In BCRPC ```getnewaddress``` is in camelCase (```getNewAddress```) and the flags are normally separated by spaces are put in strings and separated by commas. + ### List transactions We can list our previous transactions and view information about transactions such as amount and number of confirmations: From df25525768f52ae2ced958b2f2c8fa0f4ff4bc45 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:09:43 +1000 Subject: [PATCH 10/13] updated --- 18_3_Accessing_Bitcoind_with_NodeJS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/18_3_Accessing_Bitcoind_with_NodeJS.md b/18_3_Accessing_Bitcoind_with_NodeJS.md index 196bf5e..0b2ef0e 100644 --- a/18_3_Accessing_Bitcoind_with_NodeJS.md +++ b/18_3_Accessing_Bitcoind_with_NodeJS.md @@ -171,7 +171,7 @@ $ bitcoin-cli getnewaddress -addresstype legacy mtGPcBvRPZFEHo2YX8un9qqPBydhG82uuZ ``` -In BCRPC ```getnewaddress``` is in camelCase (```getNewAddress```) and the flags are normally separated by spaces are put in strings and separated by commas. +In BCRPC ```getnewaddress``` is in camelCase (```getNewAddress```) and the that flags are normally separated by spaces are instead put in strings and separated by commas. ### List transactions From 325299f087f4f48530ecdfb8c210a65ec4b0e664 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:27:48 +1000 Subject: [PATCH 11/13] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 8d6d2ee..0994bd9 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -135,7 +135,9 @@ Make sure to change your username and password to those from your ```~/.bitcoin/ The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. For example, ```bitcoin-cli getblockcount``` is ```client.GetBlockCount``` in Go. The ```connCfg``` parameters allow you to choose the Bitcoin RPC port, username, password and whether you are on testnet or mainnet. Using ```rpcclient.New(connCfg, nil)``` we configure ```client``` to connect to our Bitcoin node. -The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt" and "github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. +The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt"``` and ```"github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. + +The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. A quirk with hashes in rpcclient is that they will typically print in a different encoding if you were to print it normally with ```blockHash```. In order to print them as a string, we need to use ```blockHash.String()```. From efee6e2224ac1b99a87a07b58d44c08a84385d9b Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:33:54 +1000 Subject: [PATCH 12/13] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index 0994bd9..b6b995c 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -137,11 +137,18 @@ The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt"``` and ```"github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. -The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. +The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. After the ```defer client.Shutdown()``` line is where the exciting stuff is, like ```client.GetBlockCount()``` and ```client.GetBlockHash(blockCount)```. + +The rpcclient functions can take inputs as well, for example ```client.GetBlockHash(blockCount)``` takes the block count as an input. The ```client.GetBlockHash(blockCount)``` from above would look like this as a ```bitcoin-cli``` command: + +``` +$ bitcoin-cli getblockhash 1773561 +00000000000000346bab4126f418a5820692c9a7de7ef79717bebfccebacad61 +``` A quirk with hashes in rpcclient is that they will typically print in a different encoding if you were to print it normally with ```blockHash```. In order to print them as a string, we need to use ```blockHash.String()```. -We can run Go code with ```go run main.go```: +We can run the Go code with ```go run main.go``` and we should get an output that looks like this: ``` $ go run main.go From 1efdd57bc5f657d47892aca75d7d083671406631 Mon Sep 17 00:00:00 2001 From: Gautham Ganesh Elango Date: Wed, 1 Jul 2020 15:34:54 +1000 Subject: [PATCH 13/13] updated --- 18_1_Accessing_Bitcoind_with_Go.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/18_1_Accessing_Bitcoind_with_Go.md b/18_1_Accessing_Bitcoind_with_Go.md index b6b995c..253748a 100644 --- a/18_1_Accessing_Bitcoind_with_Go.md +++ b/18_1_Accessing_Bitcoind_with_Go.md @@ -137,7 +137,7 @@ The btcd rpcclient works by calling bitcoin-cli commands through in PascalCase. The ```import``` declaration at the top allows you to import relevant libraries. For every example here we will need to import ```"log", "fmt"``` and ```"github.com/btcsuite/btcd/rpcclient"```. We may need to import additional libraries for some examples. ```log``` is used for printing out error messages. After each time our Bitcoin node is called, we have an if statement checking if there are any errors. If there are errors, ```log``` is used to print them out. ```fmt``` is used for printing out our output. Since the examples in this document have different libraries to import, I will be showing the entire Go file, not just the specific function. -The ```defer client.Shutdown()``` line is for disconnecting the connection to our Bitcoin node from the rpcclient, once the ```main()``` function finishes executing. After the ```defer client.Shutdown()``` line is where the exciting stuff is, like ```client.GetBlockCount()``` and ```client.GetBlockHash(blockCount)```. +The ```defer client.Shutdown()``` line is for disconnecting from our Bitcoin node, once the ```main()``` function finishes executing. After the ```defer client.Shutdown()``` line is where the exciting stuff is, like ```client.GetBlockCount()``` and ```client.GetBlockHash(blockCount)```. The rpcclient functions can take inputs as well, for example ```client.GetBlockHash(blockCount)``` takes the block count as an input. The ```client.GetBlockHash(blockCount)``` from above would look like this as a ```bitcoin-cli``` command: