mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-27 00:06:26 +01:00
* Added crypto project and decoupled BitcoinSLogger from NetworkElement Decoupled BitcoinSLogger from Factory Moved NetworkElement into crypto project Moved Factory and BitcoinSUtil (renamed to BytesUtil) to crypto project Moved MaskedToString to crypto project Added BytesUtil to imports and cleaned up CryptoUtil.recoverPoint Moved the rest of crypto stuff to the crypto project Moved crypto tests to crypto-test project * Added documentation for crypto project
126 lines
3.9 KiB
Markdown
126 lines
3.9 KiB
Markdown
---
|
|
id: rpc-bitcoind
|
|
title: bitcoind/Bitcoin Core
|
|
---
|
|
|
|
> Note: `bitcoin-s-bitcoind-rpc` requires you to have `bitcoind` (Bitcoin Core daemon) installed. Grab this at [bitcoincore.org](https://bitcoincore.org/en/download/)
|
|
|
|
The Bitcoin Core RPC client in Bitcoin-S currently supports the Bitcoin Core 0.16, 0.17, 0.18, and 0.19
|
|
version lines. It can be set up to work with both local and remote Bitcoin Core servers.
|
|
|
|
You can fetch them using bitcoin-s by running the following sbt command
|
|
|
|
```bash
|
|
sbt downloadBitcoind
|
|
```
|
|
|
|
The binaries will be stored in `$HOME/.bitcoin-s/binaries/bitcoind/`
|
|
|
|
## Connecting to a local `bitcoind` instance
|
|
|
|
### Getting started quickly, with default options:
|
|
```scala mdoc:invisible
|
|
import scala.concurrent._
|
|
|
|
import java.io._
|
|
import java.net.URI
|
|
|
|
import org.bitcoins.core.config._
|
|
import org.bitcoins.rpc.config._
|
|
import org.bitcoins.rpc.client.common._
|
|
|
|
import org.bitcoins.rpc.BitcoindWalletException
|
|
import org.bitcoins.crypto._
|
|
import org.bitcoins.core.protocol._
|
|
import org.bitcoins.core.currency._
|
|
|
|
```
|
|
|
|
```scala mdoc:compile-only
|
|
|
|
implicit val ec: ExecutionContext = ExecutionContext.global
|
|
|
|
// this reads authentication credentials and
|
|
// connection details from the default data
|
|
// directory on your platform
|
|
val client = BitcoindRpcClient.fromDatadir(binary=new File("/path/to/bitcoind"), datadir=new File("/path/to/bitcoind-datadir"))
|
|
|
|
val balance: Future[Bitcoins] = for {
|
|
_ <- client.start()
|
|
balance <- client.getBalance
|
|
} yield balance
|
|
```
|
|
|
|
## Connecting to a remote `bitcoind`
|
|
|
|
First, we create a secure connection to our `bitcoind` instance by setting
|
|
up a SSH tunnel:
|
|
|
|
```bash
|
|
$ ssh -L 8332:localhost:8332 \
|
|
my-cool-user@my-cool-website.com
|
|
```
|
|
|
|
> Note: the port number '8332' is the default for mainnet. If you want to
|
|
> connect to a testnet `bitcoind`, the default port is '18332'
|
|
|
|
Now that we have a secure connection between our remote `bitcoind`, we're
|
|
ready to create the connection with our RPC client
|
|
|
|
```scala mdoc:compile-only
|
|
|
|
implicit val ec: ExecutionContext = ExecutionContext.global
|
|
|
|
val username = "FILL_ME_IN" //this username comes from 'rpcuser' in your bitcoin.conf file
|
|
val password = "FILL_ME_IN" //this password comes from your 'rpcpassword' in your bitcoin.conf file
|
|
|
|
val authCredentials = BitcoindAuthCredentials.PasswordBased(
|
|
username = username,
|
|
password = password
|
|
)
|
|
|
|
val bitcoindInstance = {
|
|
BitcoindInstance (
|
|
network = MainNet,
|
|
uri = new URI(s"http://localhost:${MainNet.port}"),
|
|
rpcUri = new URI(s"http://localhost:${MainNet.rpcPort}"),
|
|
authCredentials = authCredentials
|
|
)
|
|
}
|
|
|
|
val rpcCli = BitcoindRpcClient(bitcoindInstance)
|
|
|
|
rpcCli.getBalance.onComplete { case balance =>
|
|
println(s"Wallet balance=${balance}")
|
|
}
|
|
```
|
|
|
|
## Error handling
|
|
|
|
All errors returned by Bitcoin Core are mapped to a corresponding
|
|
[`BitcoindException`](https://github.com/bitcoin-s/bitcoin-s/blob/master/bitcoind-rpc/src/main/scala/org/bitcoins/rpc/BitcoindException.scala).
|
|
These exceptions contain an error code and a message. `BitcoindException` is a sealed
|
|
trait, which means you can easily pattern match exhaustively. Of course, other errors
|
|
could also happen: network errors, stack overflows or out-of-memory errors. The provided
|
|
class is only intended to cover errors returned by Bitcoin Core. An example of how error
|
|
handling could look:
|
|
|
|
```scala mdoc:compile-only
|
|
|
|
implicit val ec = ExecutionContext.global
|
|
|
|
// let's assume you have an already running client,
|
|
// so there's no need to start this one
|
|
val cli = BitcoindRpcClient.fromDatadir(binary=new File("/path/to/bitcoind"), datadir=new File("/path/to/bitcoind-datadir"))
|
|
|
|
// let's also assume you have a bitcoin address
|
|
val address: BitcoinAddress = ???
|
|
|
|
val txid: Future[DoubleSha256DigestBE] =
|
|
cli.sendToAddress(address, 3.bitcoins).recoverWith {
|
|
case BitcoindWalletException.UnlockNeeded(_) =>
|
|
cli.walletPassphrase("my_passphrase", 60).flatMap { _ =>
|
|
cli.sendToAddress(address, 3.bitcoins)
|
|
}
|
|
}
|
|
```
|