2021 02 10 Website fixes (#2643)

This commit is contained in:
Chris Stewart 2021-02-11 09:53:45 -06:00 committed by GitHub
parent 19b47b8eb9
commit f4d0f369ec
26 changed files with 679 additions and 262 deletions

View File

@ -18,14 +18,14 @@ $ sbt cli/universal:stage
After running that command you should find the executable here:
```bash
bitcoin-s/app/cli/target/universal/stage/bin/bitcoin-s-cli
./app/cli/target/universal/stage/bin/bitcoin-s-cli
```
### Executing commands
You can ask the client for help with
```bash
./app/cli/target/universal/stage/bin/bitcoin-s-cli --help
./app/cli/target/universal/stage/bin/bitcoin-s-cli --help
Usage: bitcoin-s-cli [options] [<cmd>]
-n, --network <value> Select the active network.

View File

@ -0,0 +1,78 @@
---
id: server-systemd
title: Systemd installation
---
### Installation
#### Linux
For server side installation you'll need to install a Java Virtual Machine first.
```bash
sudo apt install openjdk-11-jdk-headless
```
Then build a Bitcoin-S server as described above and copy it into `/usr/local`:
```bash
sudo cp -r app/server/target/universal/stage /usr/local/bitcoin-s
sudo chmod +x /usr/local/bitcoin-s/bin/bitcoin-s-server
```
The server process will run in the background and use a separate user for security reasons.
This user does not have admin rights and cannot change the system configuration.
```bash
sudo adduser bitcoins
```
In this case you'll need to put the config file into `/home/bitcoins/.bitcoin-s/bitcoin-s.conf`.
To start the server as a daemon on system startup we'll need to configure a `systemd` service.
Create `bitcoin-s.service` file using your favorite text editor.
```bash
sudo nano /etc/systemd/system/bitcoin-s.service
```
Then copy this script into the editor, then save end exit.
```bash
[Unit]
Description=Bitcoin-S Node
After=network.target
[Service]
ExecStart=/usr/local/bitcoin-s/bin/bitcoin-s-server
User=bitcoins
Group=bitcoins
Type=simple
Restart=always
RestartSec=60
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
```
Enable the service:
```bash
sudo systemctl enable bitcoin-s.service
```
Start the server.
```bash
sudo systemctl start bitcoin-s.service
```
The server will write all logs into `/var/log/syslog`.

View File

@ -31,80 +31,6 @@ This will produce a script to execute bitcoin-s which you can start with
./app/server/target/universal/stage/bin/bitcoin-s-server
```
### Installation
#### Linux
For server side installation you'll need to install a Java Virtual Machine first.
```bash
sudo apt install openjdk-11-jdk-headless
```
Then build a Bitcoin-S server as described above and copy it into `/usr/local`:
```bash
sudo cp -r app/server/target/universal/stage /usr/local/bitcoin-s
sudo chmod +x /usr/local/bitcoin-s/bin/bitcoin-s-server
```
The server process will run in the background and use a separate user for security reasons.
This user does not have admin rights and cannot change the system configuration.
```bash
sudo adduser bitcoins
```
In this case you'll need to put the config file into `/home/bitcoins/.bitcoin-s/bitcoin-s.conf`.
To start the server as a daemon on system startup we'll need to configure a `systemd` service.
Create `bitcoin-s.service` file using your favorite text editor.
```bash
sudo nano /etc/systemd/system/bitcoin-s.service
```
Then copy this script into the editor, then save end exit.
```bash
[Unit]
Description=Bitcoin-S Node
After=network.target
[Service]
ExecStart=/usr/local/bitcoin-s/bin/bitcoin-s-server
User=bitcoins
Group=bitcoins
Type=simple
Restart=always
RestartSec=60
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
```
Enable the service:
```bash
sudo systemctl enable bitcoin-s.service
```
Start the server.
```bash
sudo systemctl start bitcoin-s.service
```
The server will write all logs into `/var/log/syslog`.
### Configuration
If you would like to pass in a custom datadir for your server, you can do

View File

@ -4,7 +4,7 @@ title: Building the Oracle Server
---
The Oracle Server is a DLC Oracle with functionality for creating events and attesting to them.
The Oracle Server is interactable through the RPC interface.
You can interact with the oracle server with `bitcoin-s-cli` or `curl`
The following a guide is for how to build the oracle server.
If you are looking for the documentation on how to use the oracle server,

View File

@ -4,7 +4,7 @@ title: Oracle Server
---
The Oracle Server is a DLC Oracle with functionality for creating events and attesting to them.
The Oracle Server is interactable through the RPC interface.
You can interact with the oracle server with `bitcoin-s-cli` or `curl`
The following a guide is for interacting with the oracle
If you are looking for the documentation on how to build the oracle server,

View File

@ -5,33 +5,18 @@
"previous": "Previous",
"tagline": "Bitcoin implementation in Scala",
"docs": {
"applications/chain": {
"title": "Blockchain Verification"
},
"applications/cli": {
"title": "CLI"
},
"applications/configuration": {
"title": "Application configuration"
},
"applications/dlc": {
"title": "Executing A DLC with Bitcoin-S"
},
"applications/filter-sync": {
"title": "Syncing Blockfilters"
},
"applications/gui": {
"title": "GUI"
},
"applications/node": {
"title": "Light client"
"applications/server-systemd": {
"title": "Systemd installation"
},
"applications/server": {
"title": "Application Server"
},
"applications/wallet": {
"title": "Wallet"
},
"bips": {
"title": "Supported BIPs"
},
@ -74,9 +59,6 @@
"core/psbts": {
"title": "Partially Signed Bitcoin Transactions"
},
"core/sign": {
"title": "Sign API"
},
"core/spending-info": {
"title": "Signing Transactions"
},
@ -119,6 +101,9 @@
"oracle/oracle-election-example": {
"title": "Election Example"
},
"oracle/oracle-price-example": {
"title": "Price Example"
},
"oracle/oracle-server": {
"title": "Oracle Server"
},
@ -146,15 +131,9 @@
"wallet/address-tagging": {
"title": "Address and UTXO tagging"
},
"wallet/chain-query-api": {
"title": "Chain Query API"
},
"wallet/dlc": {
"title": "Executing A DLC with Bitcoin-S"
},
"wallet/node-api": {
"title": "Node API"
},
"wallet/wallet-callbacks": {
"title": "Wallet Callbacks"
},
@ -487,6 +466,144 @@
},
"version-0.4.0/wallet/version-v0.4-wallet": {
"title": "Wallet"
},
"version-0.5.0/applications/version-0.5.0-cli": {
"title": "CLI"
},
"version-0.5.0/applications/version-0.5.0-gui": {
"title": "GUI"
},
"version-0.5.0/applications/version-0.5.0-server-systemd": {
"title": "Systemd installation"
},
"version-0.5.0/applications/version-0.5.0-server": {
"title": "Application Server"
},
"version-0.5.0/version-0.5.0-bips": {
"title": "Supported BIPs"
},
"version-0.5.0/chain/version-0.5.0-chain-query-api": {
"title": "Chain Query API"
},
"version-0.5.0/chain/version-0.5.0-chain": {
"title": "Blockchain Verification"
},
"version-0.5.0/chain/version-0.5.0-filter-sync": {
"title": "Syncing Blockfilters"
},
"version-0.5.0/config/version-0.5.0-configuration": {
"title": "Application Configuration"
},
"version-0.5.0/version-0.5.0-contributing-website": {
"title": "Contributing to the website"
},
"version-0.5.0/version-0.5.0-contributing": {
"title": "Contributing"
},
"version-0.5.0/core/version-0.5.0-adding-spks": {
"title": "Adding New Script Types"
},
"version-0.5.0/core/version-0.5.0-addresses": {
"title": "Generating Addresses"
},
"version-0.5.0/core/version-0.5.0-core-intro": {
"title": "Core Module"
},
"version-0.5.0/core/version-0.5.0-dlc": {
"title": "Discreet Log Contract Data Structures"
},
"version-0.5.0/core/version-0.5.0-hd-keys": {
"title": "HD Key Generation"
},
"version-0.5.0/core/version-0.5.0-lightning-network": {
"title": "Lightning Network Data Types"
},
"version-0.5.0/core/version-0.5.0-psbts": {
"title": "Partially Signed Bitcoin Transactions"
},
"version-0.5.0/core/version-0.5.0-spending-info": {
"title": "Signing Transactions"
},
"version-0.5.0/core/version-0.5.0-txbuilder": {
"title": "TxBuilder Example"
},
"version-0.5.0/crypto/version-0.5.0-adaptor-signatures": {
"title": "Adaptor Signatures"
},
"version-0.5.0/crypto/version-0.5.0-crypto-intro": {
"title": "Crypto Module"
},
"version-0.5.0/crypto/version-0.5.0-sign": {
"title": "Sign API"
},
"version-0.5.0/fee-provider/version-0.5.0-fee-provider": {
"title": "Fee Provider"
},
"version-0.5.0/version-0.5.0-getting-setup": {
"title": "Getting Bitcoin-S installed on your machine"
},
"version-0.5.0/version-0.5.0-getting-started": {
"title": "Intro and Getting Started"
},
"version-0.5.0/key-manager/version-0.5.0-key-manager": {
"title": "Key Manager"
},
"version-0.5.0/key-manager/version-0.5.0-server-key-manager": {
"title": "Server Key Manager"
},
"version-0.5.0/node/version-0.5.0-node-api": {
"title": "Node API"
},
"version-0.5.0/node/version-0.5.0-node": {
"title": "Light Client"
},
"version-0.5.0/oracle/version-0.5.0-build-oracle-server": {
"title": "Building the Oracle Server"
},
"version-0.5.0/oracle/version-0.5.0-oracle-election-example": {
"title": "Election Example"
},
"version-0.5.0/oracle/version-0.5.0-oracle-price-example": {
"title": "Price Example"
},
"version-0.5.0/oracle/version-0.5.0-oracle-server": {
"title": "Oracle Server"
},
"version-0.5.0/rpc/version-0.5.0-rpc-bitcoind": {
"title": "bitcoind/Bitcoin Core"
},
"version-0.5.0/rpc/version-0.5.0-rpc-eclair": {
"title": "Eclair"
},
"version-0.5.0/secp256k1/version-0.5.0-jni-modify": {
"title": "Adding to Secp256k1 JNI"
},
"version-0.5.0/secp256k1/version-0.5.0-secp256k1": {
"title": "Secp256k1"
},
"version-0.5.0/testkit/version-0.5.0-testkit": {
"title": "Testkit"
},
"version-0.5.0/wallet/version-0.5.0-address-tagging": {
"title": "Address and UTXO tagging"
},
"version-0.5.0/wallet/version-0.5.0-dlc": {
"title": "Executing A DLC with Bitcoin-S"
},
"version-0.5.0/wallet/version-0.5.0-wallet-callbacks": {
"title": "Wallet Callbacks"
},
"version-0.5.0/wallet/version-0.5.0-wallet-get-address": {
"title": "Wallet Get Address APIs"
},
"version-0.5.0/wallet/version-0.5.0-wallet-rescan": {
"title": "Wallet Rescans"
},
"version-0.5.0/wallet/version-0.5.0-wallet-sync": {
"title": "Wallet Sync"
},
"version-0.5.0/wallet/version-0.5.0-wallet": {
"title": "Wallet"
}
},
"links": {

View File

@ -10,7 +10,8 @@
"Applications": [
"applications/cli",
"applications/server",
"applications/gui"
"applications/gui",
"applications/server-systemd"
],
"Chain": [
"chain/chain",

View File

@ -19,14 +19,14 @@ $ sbt cli/universal:stage
After running that command you should find the executable here:
```bash
bitcoin-s/app/cli/target/universal/stage/bin/bitcoin-s-cli
./app/cli/target/universal/stage/bin/bitcoin-s-cli
```
### Executing commands
You can ask the client for help with
```bash
./app/cli/target/universal/stage/bin/bitcoin-s-cli --help
./app/cli/target/universal/stage/bin/bitcoin-s-cli --help
Usage: bitcoin-s-cli [options] [<cmd>]
-n, --network <value> Select the active network.
@ -36,4 +36,27 @@ Usage: bitcoin-s-cli [options] [<cmd>]
```
Now you are are ready to start the server that the cli sends commands to. Take a look at our [server](server.md) documentation on how to build and start the server.
Now you are are ready to start the server that the cli sends commands to. Take a look at our [server](server.md) documentation on how to build and start the server.
### Native binaries
Bitcoin-s also supports building native executables for various platforms supported by the [graalvm native image](https://www.graalvm.org/reference-manual/native-image/) tool.
You can build by using the [native image plugin for sbt](https://github.com/scalameta/sbt-native-image). This will download the appropriate graalvm
version and the native image tool, and then build the cli
```bashrc
sbt cli/nativeImage
```
After the build is done, you can find the artifact here locally
```bashrc
app/cli/target/native-image/bitcoin-s-cli
```
We also publish native image binaries every time we merge a commit to master on github.
As an example, you can [see the artifacts](https://github.com/bitcoin-s/bitcoin-s/actions?query=workflow%3A%22Native+Image+bitcoin-s-cli%22)
in the upper right hand corner.
If you don't want to build the `bitcoin-s-cli` yourself, you can download it for your platform there.

View File

@ -0,0 +1,79 @@
---
id: version-0.5.0-server-systemd
title: Systemd installation
original_id: server-systemd
---
### Installation
#### Linux
For server side installation you'll need to install a Java Virtual Machine first.
```bash
sudo apt install openjdk-11-jdk-headless
```
Then build a Bitcoin-S server as described above and copy it into `/usr/local`:
```bash
sudo cp -r app/server/target/universal/stage /usr/local/bitcoin-s
sudo chmod +x /usr/local/bitcoin-s/bin/bitcoin-s-server
```
The server process will run in the background and use a separate user for security reasons.
This user does not have admin rights and cannot change the system configuration.
```bash
sudo adduser bitcoins
```
In this case you'll need to put the config file into `/home/bitcoins/.bitcoin-s/bitcoin-s.conf`.
To start the server as a daemon on system startup we'll need to configure a `systemd` service.
Create `bitcoin-s.service` file using your favorite text editor.
```bash
sudo nano /etc/systemd/system/bitcoin-s.service
```
Then copy this script into the editor, then save end exit.
```bash
[Unit]
Description=Bitcoin-S Node
After=network.target
[Service]
ExecStart=/usr/local/bitcoin-s/bin/bitcoin-s-server
User=bitcoins
Group=bitcoins
Type=simple
Restart=always
RestartSec=60
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
```
Enable the service:
```bash
sudo systemctl enable bitcoin-s.service
```
Start the server.
```bash
sudo systemctl start bitcoin-s.service
```
The server will write all logs into `/var/log/syslog`.

View File

@ -32,80 +32,6 @@ This will produce a script to execute bitcoin-s which you can start with
./app/server/target/universal/stage/bin/bitcoin-s-server
```
### Installation
#### Linux
For server side installation you'll need to install a Java Virtual Machine first.
```bash
sudo apt install openjdk-11-jdk-headless
```
Then build a Bitcoin-S server as described above and copy it into `/usr/local`:
```bash
sudo cp -r app/server/target/universal/stage /usr/local/bitcoin-s
sudo chmod +x /usr/local/bitcoin-s/bin/bitcoin-s-server
```
The server process will run in the background and use a separate user for security reasons.
This user does not have admin rights and cannot change the system configuration.
```bash
sudo adduser bitcoins
```
In this case you'll need to put the config file into `/home/bitcoins/.bitcoin-s/bitcoin-s.conf`.
To start the server as a daemon on system startup we'll need to configure a `systemd` service.
Create `bitcoin-s.service` file using your favorite text editor.
```bash
sudo nano /etc/systemd/system/bitcoin-s.service
```
Then copy this script into the editor, then save end exit.
```bash
[Unit]
Description=Bitcoin-S Node
After=network.target
[Service]
ExecStart=/usr/local/bitcoin-s/bin/bitcoin-s-server
User=bitcoins
Group=bitcoins
Type=simple
Restart=always
RestartSec=60
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
```
Enable the service:
```bash
sudo systemctl enable bitcoin-s.service
```
Start the server.
```bash
sudo systemctl start bitcoin-s.service
```
The server will write all logs into `/var/log/syslog`.
### Configuration
If you would like to pass in a custom datadir for your server, you can do

View File

@ -169,7 +169,7 @@ bitcoin-s {
# to keep the sync time fast, however, for regtest it should be small
# so it does not exceed the chain size.
filter-batch-size = 100
filter-batch-size = 1000
}
hikari-logging = true
@ -212,7 +212,7 @@ bitcoin-s {
# bip39password = "changeMe"
# Password that your seed is encrypted with
aespassword = changeMe
aesPassword = changeMe
}
# Bitcoin-S provides manny different fee providers
@ -245,6 +245,11 @@ bitcoin-s {
# The ip address we bind our server too
rpcbind = "127.0.0.1"
}
oracle {
hikari-logging = true
hikari-logging-interval = 1 minute
}
}

View File

@ -119,7 +119,6 @@ object P2PKWithTimeoutScriptPubKey
buildScript(
asm = asm.toVector,
constructor = P2PKWithTimeoutScriptPubKeyImpl.apply,
invariant = isP2PKWithTimeoutScriptPubKey,
errorMsg = s"Given asm was not a P2PKWithTimeoutScriptPubKey, got $asm"
)
}
@ -146,7 +145,7 @@ object P2PKWithTimeoutScriptPubKey
)
}
def isP2PKWithTimeoutScriptPubKey(asm: Seq[ScriptToken]): Boolean = {
override def isValidAsm(asm: Seq[ScriptToken]): Boolean = {
if (asm.length == 12) {
val pubKey = ECPublicKey.fromBytes(asm(2).bytes)
val lockTimeTry = Try(ScriptNumber.fromBytes(asm(5).bytes))
@ -171,7 +170,7 @@ We now need to ensure that `ScriptPubKey.fromAsm(p2pkWithTimeoutSPK.asm)` return
```scala
asm match {
case Nil => EmptyScriptPubKey
case _ if P2PKWithTimeoutScriptPubKey.isP2PKWithTimeoutScriptPubKey(asm) =>
case _ if P2PKWithTimeoutScriptPubKey.isValidAsm(asm) =>
P2PKWithTimeoutScriptPubKey.fromAsm(asm)
//...
}
@ -208,7 +207,6 @@ object P2PKScriptSignature extends ScriptFactory[P2PKScriptSignature] {
def fromAsm(asm: Seq[ScriptToken]): P2PKScriptSignature = {
buildScript(asm.toVector,
P2PKScriptSignatureImpl(_),
isP2PKScriptSignature(_),
"The given asm tokens were not a p2pk script sig: " + asm)
}
@ -220,7 +218,7 @@ object P2PKScriptSignature extends ScriptFactory[P2PKScriptSignature] {
}
/** P2PK scriptSigs always have the pattern [pushop, digitalSignature] */
def isP2PKScriptSignature(asm: Seq[ScriptToken]): Boolean = asm match {
override def isValidAsm(asm: Seq[ScriptToken]): Boolean = asm match {
case Seq(_: BytesToPushOntoStack, _: ScriptConstant) => true
case _ => false
}
@ -242,7 +240,6 @@ object P2PKWithTimeoutScriptSignature
buildScript(
asm.toVector,
ConditionalScriptSignature.fromAsm,
isP2PKWithTimeoutScriptSignature,
s"The given asm tokens were not a P2PKWithTimeoutScriptSignature, got $asm"
)
}
@ -253,9 +250,9 @@ object P2PKWithTimeoutScriptSignature
ConditionalScriptSignature(P2PKScriptSignature(signature), beforeTimeout)
}
def isP2PKWithTimeoutScriptSignature(asm: Seq[ScriptToken]): Boolean = {
P2PKScriptSignature.isP2PKScriptSignature(asm.dropRight(1)) && ConditionalScriptSignature
.isValidConditionalScriptSig(asm)
override def isValidAsm(asm: Seq[ScriptToken]): Boolean = {
P2PKScriptSignature.isValidAsm(asm.dropRight(1)) && ConditionalScriptSignature
.isValidAsm(asm)
}
}
```
@ -269,7 +266,7 @@ If you added a new `ScriptSignature` type in the previous step, you must add a `
```scala
tokens match {
//...
case _ if P2PKScriptSignature.isP2PKScriptSignature(tokens) =>
case _ if P2PKScriptSignature.isValidAsm(tokens) =>
P2PKScriptSignature.fromAsm(tokens)
//...
}

View File

@ -27,7 +27,7 @@ reason to keep using legacy transaction formats.
val privkey = ECPrivateKey()
// privkey: ECPrivateKey = Masked(ECPrivateKeyImpl)
val pubkey = privkey.publicKey
// pubkey: org.bitcoins.crypto.ECPublicKey = ECPublicKey(03ed489d35084305e77a39dddd28dd49efbc6ceabb8a4226c09283d1a58babe149)
// pubkey: org.bitcoins.crypto.ECPublicKey = ECPublicKey(0247d73749f1c06647783d92be2f1a0a279b52bdff16f3506d090698c94563695c)
val segwitAddress = {
// see https://bitcoin.org/en/glossary/pubkey-script
@ -36,10 +36,10 @@ val segwitAddress = {
val scriptPubKey = P2WPKHWitnessSPKV0(pubkey)
Bech32Address(scriptPubKey, TestNet3)
}
// segwitAddress: Bech32Address = tb1qfu70elqscctfxxf0efd0trywlgee7s7szkjax9
// segwitAddress: Bech32Address = tb1q0uxf6jpf067gqu7cugx36h5gfxpq4yu3mhz437
println(segwitAddress.toString)
// tb1qfu70elqscctfxxf0efd0trywlgee7s7szkjax9
// tb1q0uxf6jpf067gqu7cugx36h5gfxpq4yu3mhz437
```
## Generating legacy (base58) addresses
@ -52,8 +52,8 @@ Take a look:
// we're reusing the same private/public key pair
// from before. don't do this in an actual application!
val legacyAddress = P2PKHAddress(pubkey, TestNet3)
// legacyAddress: P2PKHAddress = mnjvjk8q4ieBvZMDxBRvLQu1yqRPdQeMWy
// legacyAddress: P2PKHAddress = ms6jDswfca7QCj2tVYq1rRpVU8JomRPva5
println(legacyAddress.toString)
// mnjvjk8q4ieBvZMDxBRvLQu1yqRPdQeMWy
// ms6jDswfca7QCj2tVYq1rRpVU8JomRPva5
```

File diff suppressed because one or more lines are too long

View File

@ -30,13 +30,13 @@ import org.bitcoins.core.hd._
// how long our phrase ends up being
// 256 bits of entropy results in 24 words
val entropy: BitVector = MnemonicCode.getEntropy256Bits
// entropy: BitVector = BitVector(256 bits, 0xcfe93e6d8c654448bb38c068ae4853b22fa2a89d62fdb4907f7ac6f7d4295e56)
// entropy: BitVector = BitVector(256 bits, 0xb39105335b179bc75b1b3bc2f98a72558824b836d30dc2f827a0deff62263933)
val mnemonicCode = MnemonicCode.fromEntropy(entropy)
// mnemonicCode: MnemonicCode = Masked(MnemonicCodeImpl)
mnemonicCode.words // the phrase the user should write down
// res0: Vector[String] = Vector(soup, enemy, opinion, boat, february, cattle, undo, blossom, hamster, inch, belt, gold, when, february, intact, garden, region, loop, team, mistake, later, believe, junk, surge) // the phrase the user should write down
// res0: Vector[String] = Vector(receive, market, error, renew, keen, together, hockey, guess, seed, slush, orient, prison, liquid, foster, swap, giant, seed, scorpion, trial, sadness, wage, basic, tooth, husband) // the phrase the user should write down
// the password argument is an optional, extra security
// measure. all MnemonicCode instances will give you a
@ -52,7 +52,7 @@ val xpriv = ExtPrivateKey.fromBIP39Seed(ExtKeyVersion.SegWitMainNetPriv,
bip39Seed)
// xpriv: ExtPrivateKey = Masked(ExtPrivateKeyImpl)
val xpub = xpriv.extPublicKey
// xpub: ExtPublicKey = zpub6jftahH18ngZxdmz7nMS7aCRBepzXLyx7Sh5q9x5KKzGVX95Mm4ndgxSotps9YNMwBRJ8STGbzY2zKPG5Rix9MJrTDxZsL38HfvnSL7e8b4
// xpub: ExtPublicKey = zpub6jftahH18ngZxm7szuMGGg1mZxk46iojb4ya9Smp9rNXzqj6EpBRHBTxVPDPfz9ihomPxpQqkSRbVBJDwY17V37uNiMYA5WpCDwCPi2RgHi
// you can now use the generated xpriv to derive further
// private or public keys
@ -103,7 +103,7 @@ val accountXpub = {
// can generate addresses with it!
accountXpriv.extPublicKey
}
// accountXpub: ExtPublicKey = zpub6s4sPFinAeiNuecqUkCFdFy7rbWhS5gFQ7TtVRo2hQpgpba9z1C9ppgtyjy6kVJjPKzF5JPfuSfW2ziK2Z7FxUFiHjRyPxL2rGjW1ay4DAJ
// accountXpub: ExtPublicKey = zpub6rsUPkH6CLypi8pcGf1Uu9DZCiWH8SMt4X6biYGbQHhaCX5BGBm9mA8fPRS64dGuXqgQBnGATUSPStG7RFAZgeakrrkH2irxBqh9QSrzK1b
// address no. 0 ---------------┐
// external address ----------┐ |
@ -126,12 +126,12 @@ val firstAccountAddress = {
val scriptPubKey = P2WPKHWitnessSPKV0(pubkey)
Bech32Address(scriptPubKey, TestNet3)
}
// firstAccountAddress: Bech32Address = tb1qvzst4c3q0tggykc09fl2q2g9ck26dmqrk3v7mc
// firstAccountAddress: Bech32Address = tb1qccq4vzhchs23sjf9xgjlv7jyut5d9nqhhnnwh2
// tada! We just generated an address you can send money to,
// without having access to the private key!
firstAccountAddress.value
// res2: String = tb1qvzst4c3q0tggykc09fl2q2g9ck26dmqrk3v7mc
// res2: String = tb1qccq4vzhchs23sjf9xgjlv7jyut5d9nqhhnnwh2
// you can now continue deriving addresses from the same public
// key, by imitating what we did above. To get the next

View File

@ -9,7 +9,7 @@ Bitcoin-S features a transaction building API that allows you to construct and s
```scala
implicit val ec: ExecutionContext = ExecutionContext.Implicits.global
// ec: ExecutionContext = scala.concurrent.impl.ExecutionContextImpl$$anon$3@4a88bb8f[Running, parallelism = 12, size = 3, active = 0, running = 0, steals = 6, tasks = 0, submissions = 0]
// ec: ExecutionContext = scala.concurrent.impl.ExecutionContextImpl$$anon$3@3f5ad718[Running, parallelism = 16, size = 4, active = 0, running = 0, steals = 18, tasks = 0, submissions = 0]
// Initialize a transaction builder
val builder = RawTxBuilder()
@ -19,19 +19,19 @@ val builder = RawTxBuilder()
val privKey = ECPrivateKey.freshPrivateKey
// privKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
val pubKey = privKey.publicKey
// pubKey: ECPublicKey = ECPublicKey(0247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275)
// pubKey: ECPublicKey = ECPublicKey(0390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a)
// this is the script that the TxBuilder is going to create a
// script signature that validly spends this scriptPubKey
val creditingSpk = P2PKHScriptPubKey(pubKey = privKey.publicKey)
// creditingSpk: P2PKHScriptPubKey = pkh(8eb97edd6737c412e761efb8736ea84574a38d61)
// creditingSpk: P2PKHScriptPubKey = pkh(78f4a30c70decd2478a0d673f1ddc87c9b5abc44)
val amount = 10000.satoshis
// amount: Satoshis = 10000 sats
// this is the UTXO we are going to be spending
val utxo =
TransactionOutput(value = amount, scriptPubKey = creditingSpk)
// utxo: TransactionOutput = TransactionOutput(10000 sats,pkh(8eb97edd6737c412e761efb8736ea84574a38d61))
// utxo: TransactionOutput = TransactionOutput(10000 sats,pkh(78f4a30c70decd2478a0d673f1ddc87c9b5abc44))
// the private key that locks the funds for the script we are spending too
val destinationPrivKey = ECPrivateKey.freshPrivateKey
@ -44,7 +44,7 @@ val destinationAmount = 5000.satoshis
// the script that corresponds to destination private key, this is what is receiving the money
val destinationSPK =
P2PKHScriptPubKey(pubKey = destinationPrivKey.publicKey)
// destinationSPK: P2PKHScriptPubKey = pkh(bd9274c3a52f9afb9e3573d2d39ca554a343c801)
// destinationSPK: P2PKHScriptPubKey = pkh(4606b8a9405b45223d6bfd3ce64f11f8616441fd)
// this is where we are sending money too
// we could add more destinations here if we
@ -55,7 +55,7 @@ val destinations = {
Vector(destination0)
}
// destinations: Vector[TransactionOutput] = Vector(TransactionOutput(5000 sats,pkh(bd9274c3a52f9afb9e3573d2d39ca554a343c801)))
// destinations: Vector[TransactionOutput] = Vector(TransactionOutput(5000 sats,pkh(4606b8a9405b45223d6bfd3ce64f11f8616441fd)))
// Add the destinations to the tx builder
builder ++= destinations
@ -68,17 +68,17 @@ val creditingTx = BaseTransaction(version = Int32.one,
inputs = Vector.empty,
outputs = Vector(utxo),
lockTime = UInt32.zero)
// creditingTx: BaseTransaction = BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(8eb97edd6737c412e761efb8736ea84574a38d61))),UInt32Impl(0))
// creditingTx: BaseTransaction = BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(78f4a30c70decd2478a0d673f1ddc87c9b5abc44))),UInt32Impl(0))
// this is the information we need from the crediting TX
// to properly "link" it in the transaction we are creating
val outPoint = TransactionOutPoint(creditingTx.txId, UInt32.zero)
// outPoint: TransactionOutPoint = TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0)
// outPoint: TransactionOutPoint = TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0)
val input = TransactionInput(
outPoint,
EmptyScriptSignature,
sequenceNumber = UInt32.zero)
// input: TransactionInput = TransactionInputImpl(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),EmptyScriptSignature,UInt32Impl(0))
// input: TransactionInput = TransactionInputImpl(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),EmptyScriptSignature,UInt32Impl(0))
// Add a new input to our builder
builder += input
@ -86,11 +86,11 @@ builder += input
// We can now generate a RawTxBuilderResult ready to be finalized
val builderResult = builder.result()
// builderResult: RawTxBuilderResult = RawTxBuilderResult(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(bd9274c3a52f9afb9e3573d2d39ca554a343c801))),UInt32Impl(0))
// builderResult: RawTxBuilderResult = RawTxBuilderResult(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(4606b8a9405b45223d6bfd3ce64f11f8616441fd))),UInt32Impl(0))
// this contains the information needed to analyze our input during finalization
val inputInfo = P2PKHInputInfo(outPoint, amount, privKey.publicKey)
// inputInfo: P2PKHInputInfo = P2PKHInputInfo(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),10000 sats,ECPublicKey(0247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275))
// inputInfo: P2PKHInputInfo = P2PKHInputInfo(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),10000 sats,ECPublicKey(0390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a))
// this is how much we are going to pay as a fee to the network
// for this example, we are going to pay 1 satoshi per byte
@ -100,18 +100,18 @@ val feeRate = SatoshisPerByte(1.satoshi)
val changePrivKey = ECPrivateKey.freshPrivateKey
// changePrivKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
val changeSPK = P2PKHScriptPubKey(pubKey = changePrivKey.publicKey)
// changeSPK: P2PKHScriptPubKey = pkh(b96df742d95c8cd0484a5b6b61bc0bd16c44e68f)
// changeSPK: P2PKHScriptPubKey = pkh(1e2744c8005bbafe939e0ff625fd43fc385bcc6c)
// We chose a finalizer that adds a change output to our tx based on a fee rate
val finalizer = StandardNonInteractiveFinalizer(
Vector(inputInfo),
feeRate,
changeSPK)
// finalizer: StandardNonInteractiveFinalizer = StandardNonInteractiveFinalizer(Vector(P2PKHInputInfo(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),10000 sats,ECPublicKey(0247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275))),1 sats/byte,pkh(b96df742d95c8cd0484a5b6b61bc0bd16c44e68f))
// finalizer: StandardNonInteractiveFinalizer = StandardNonInteractiveFinalizer(Vector(P2PKHInputInfo(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),10000 sats,ECPublicKey(0390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a))),1 sats/byte,pkh(1e2744c8005bbafe939e0ff625fd43fc385bcc6c))
// We can now finalize the tx builder result from earlier with this finalizer
val unsignedTxF: Future[Transaction] = finalizer.buildTx(builderResult)
// unsignedTxF: Future[Transaction] = Future(Success(BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(bd9274c3a52f9afb9e3573d2d39ca554a343c801)), TransactionOutput(4775 sats,pkh(b96df742d95c8cd0484a5b6b61bc0bd16c44e68f))),UInt32Impl(0))))
// unsignedTxF: Future[Transaction] = Future(Success(BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(4606b8a9405b45223d6bfd3ce64f11f8616441fd)), TransactionOutput(4775 sats,pkh(1e2744c8005bbafe939e0ff625fd43fc385bcc6c))),UInt32Impl(0))))
// We now turn to signing the unsigned transaction
// this contains all the information we need to
@ -121,12 +121,12 @@ val utxoInfo = ScriptSignatureParams(inputInfo = inputInfo,
signers = Vector(privKey),
hashType =
HashType.sigHashAll)
// utxoInfo: ScriptSignatureParams[P2PKHInputInfo] = ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),10000 sats,ECPublicKey(0247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(8eb97edd6737c412e761efb8736ea84574a38d61))),UInt32Impl(0)),Vector(Masked(ECPrivateKeyImpl)),SIGHASH_ALL(Int32Impl(1)))
// utxoInfo: ScriptSignatureParams[P2PKHInputInfo] = ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),10000 sats,ECPublicKey(0390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(78f4a30c70decd2478a0d673f1ddc87c9b5abc44))),UInt32Impl(0)),Vector(Masked(ECPrivateKeyImpl)),SIGHASH_ALL(Int32Impl(1)))
// all of the UTXO spending information, since we only have
// one input, this is just one element
val utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(utxoInfo)
// utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),10000 sats,ECPublicKey(0247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(8eb97edd6737c412e761efb8736ea84574a38d61))),UInt32Impl(0)),Vector(Masked(ECPrivateKeyImpl)),SIGHASH_ALL(Int32Impl(1))))
// utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),10000 sats,ECPublicKey(0390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(78f4a30c70decd2478a0d673f1ddc87c9b5abc44))),UInt32Impl(0)),Vector(Masked(ECPrivateKeyImpl)),SIGHASH_ALL(Int32Impl(1))))
// Yay! Now we use the RawTxSigner object to sign the tx.
// The 'sign' method is going produce a validly signed transaction
@ -146,7 +146,7 @@ val signedTx: Transaction = {
}
Await.result(signedTxF, 30.seconds)
}
// signedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(2f5aad3171a536cb026985839759b13d8c63087cba562864d8f8533e5df03e4b:0),P2PKHScriptSignature(ECPublicKey(0247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275), ECDigitalSignature(3044022035aceab2a6ca11a6be9619a5be58ba085aab3bb83bc89f9bf316fd0eaf8bc7b802204f8d704a23e8695db7b89c6ea0c0e134065449c2fa0934b6e2a9853ba396992c01)),UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(bd9274c3a52f9afb9e3573d2d39ca554a343c801)), TransactionOutput(4775 sats,pkh(b96df742d95c8cd0484a5b6b61bc0bd16c44e68f))),UInt32Impl(0))
// signedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(1370cec8820efad65001bfbd82b5e6efddbaab7e619dfa2865fd5cdf799be45f:0),P2PKHScriptSignature(ECPublicKey(0390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a), ECDigitalSignature(3044022033bcd24a8a264f29860594f27c03b1c8995d9b917b5d37e9a02561a83352483902204d3a39a8ab95ce3a82a664d0864a45f61da30bd59c7b102b97b76ed0b5c8086801)),UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(4606b8a9405b45223d6bfd3ce64f11f8616441fd)), TransactionOutput(4775 sats,pkh(1e2744c8005bbafe939e0ff625fd43fc385bcc6c))),UInt32Impl(0))
```
```scala
@ -158,5 +158,5 @@ signedTx.outputs.length
//remember, you can call .hex on any bitcoin-s data structure to get the hex representation!
signedTx.hex
// res4: String = 02000000014b3ef05d3e53f8d8642856ba7c08638c3db1599783856902cb36a57131ad5a2f000000006a473044022035aceab2a6ca11a6be9619a5be58ba085aab3bb83bc89f9bf316fd0eaf8bc7b802204f8d704a23e8695db7b89c6ea0c0e134065449c2fa0934b6e2a9853ba396992c01210247a89402a39ac482d4591138eefd872e0450b157ba529621cb6f25abc8b28275000000000288130000000000001976a914bd9274c3a52f9afb9e3573d2d39ca554a343c80188aca7120000000000001976a914b96df742d95c8cd0484a5b6b61bc0bd16c44e68f88ac00000000
// res4: String = 02000000015fe49b79df5cfd6528fa9d617eabbaddefe6b582bdbf0150d6fa0e82c8ce7013000000006a473044022033bcd24a8a264f29860594f27c03b1c8995d9b917b5d37e9a02561a83352483902204d3a39a8ab95ce3a82a664d0864a45f61da30bd59c7b102b97b76ed0b5c8086801210390a4b4751987bee83f38b4339919ec93fd83049c2b276958982357d82af9bc4a000000000288130000000000001976a9144606b8a9405b45223d6bfd3ce64f11f8616441fd88aca7120000000000001976a9141e2744c8005bbafe939e0ff625fd43fc385bcc6c88ac00000000
```

View File

@ -0,0 +1,40 @@
---
id: version-0.5.0-adaptor-signatures
title: Adaptor Signatures
original_id: adaptor-signatures
---
Bitcoin-S now has support for an old experimental version of [ECDSA Adaptor Signatures](https://github.com/jonasnick/secp256k1/pull/14). This old version will soon be replaced by a newer version which is [being specified](https://github.com/discreetlogcontracts/dlcspecs/blob/03bf7095c2016e1ce9c9fb612920872d4456f179/ECDSA-adaptor.md) but in the meantime, bitcoin-s' version can still be used to experiment with applications of ECDSA adaptor signatures as it has a similar interface.
There are four relevant functions to adaptor signatures:
* `sign`
* This function belongs to `ECPrivateKey` and creates an adaptor signature given a message (`ByteVector`) and an adaptor point (`ECPublicKey`).
* `verify`
* Verifies an adaptor signature given the signing public key, the message and the adaptor point.
* `complete`
* This function belongs to `ECPrivateKey` and computes a valid ECDSA signature given a valid adaptor signature whose adaptor point is this private key's public key.
* `extract`
* This function belongs to `ECPublicKey` and computes the adaptor secret (private key to this public key) given a valid adaptor signature for this adaptor point, and the valid ECDSA signature computed using `complete`.
The following code shows each function to do with adaptor signature usage:
```scala
// Alice generages an adaptor signature using her private key and the adaptor point
val adaptorSig = privKey.adaptorSign(adaptorPoint, msg)
// Bob verifies this adaptor signature using Alice's public key and the adaptor point
require(pubKey.adaptorVerify(msg, adaptorPoint, adaptorSig))
// Bob computes a valid ECDSA signature using the adaptorSignature, which he knows
val sig = adaptorSecret.completeAdaptorSignature(adaptorSig)
// Anyone can validate this signature
require(pubKey.verify(msg, sig))
// Alice can compute the adaptor secret from the signatures
val secret = adaptorPoint.extractAdaptorSecret(adaptorSig, sig)
require(secret == adaptorSecret)
```

View File

@ -51,13 +51,13 @@ val extPrivKey = ExtPrivateKey(ExtKeyVersion.SegWitMainNetPriv)
// extPrivKey: ExtPrivateKey = Masked(ExtPrivateKeyImpl)
extPrivKey.sign(DoubleSha256Digest.empty.bytes)
// res0: ECDigitalSignature = ECDigitalSignature(3045022100c911f42f331c0569d1b9b77026df50b39bb683ba81f6991a4131e9bc5276f796022014a0fa786ac3e5d8443fe98e5feda55f8639f599e344e5d5b50d345aee3f008d)
// res0: ECDigitalSignature = ECDigitalSignature(30440220530bbdcebde7df249e63340120dde70badb0c2a7d6f2e4ab4ccc34a99e0be85d0220118d3d5be4d95a65b52d42d3b9312ce8c201621cd7d02c7d706c46fd2ed9a5e4)
val path = BIP32Path(Vector(BIP32Node(0,false)))
// path: BIP32Path = m/0
extPrivKey.sign(DoubleSha256Digest.empty.bytes,path)
// res1: ECDigitalSignature = ECDigitalSignature(3044022021022d5aed760a932276f35908a9b8d6865be7f31e8f16479dfdfbae6a314b3602203c9265bd2632417904dabefe8ebaac3fe832ccf9997e81d92e0606e62e7061ba)
// res1: ECDigitalSignature = ECDigitalSignature(30440220776d7530cfc12ce376e38bd23e71a95177830205a26518812afd4f7516858c6a022077cbd5a19761434f84b6b442788f02cc37b930acf169c13f13f1b6930ce1ea78)
```
With `ExtSign`, you can use `ExtPrivateKey` to sign transactions inside of `TxBuilder` since `UTXOSpendingInfo` takes in `Sign` as a parameter.

View File

@ -134,7 +134,7 @@ If you're looking to set up a DLC Oracle instead go to the [oracle server docs](
We are finally ready to start running some programs! Follow the [instructions here](applications/server.md#building-the-server) to build the server. Then, follow [these instructions](applications/cli.md) to setup the CLI.
There are 2 ways to use the bitcoin-s server. It can either can be as a neutrino node or use bitcoind as a backend.
There are 2 ways to use the bitcoin-s server. It can either be as a neutrino node or use bitcoind as a backend.
This can be configured by the configuration option `bitcoin-s.node.mode` choosing either `neutrino` or `bitcoind`.
### Option A: Neutrino Server
@ -151,7 +151,7 @@ Testnet:
`bitcoin-s.node.peers = ["neutrino.testnet3.suredbits.com:18333"]`
If you would like to use your own node you can either use the bitcoind backend option or connect to your own compatible node.
There is no released version of bitcoind that is neutrino compatible so you will either have to compile the latest `master` yourself, or use the experimental version provided by running `sbt downloadBitcoind`.
There is no released version of bitcoind that is neutrino compatible, so you will either have to compile the latest `master` yourself, or use the experimental version provided by running `sbt downloadBitcoind`.
After building your bitcoin-s server, properly configuring it to be in `neutrino` mode you can start your server with:
@ -201,10 +201,17 @@ bitcoin-s {
## Step 6 (Optional): Moving To Testnet
To run your Bitcoin-S Server on testnet, simply change `network = testnet3` and change your `peers = ["neutrino.testnet3.suredbits.com:18333"] ` in your `.bitcoin-s/bitcoin-s.conf` file. This will allow you to connect to Suredbits' neutrino-enabled `bitcoind` node. Keep in mind then when you restart your server, it will begin initial sync which will take many hours as all block filters for all testnet blocks will be downloaded. If you wish to speed this process up, download [this snapshot](https://s3-us-west-2.amazonaws.com/www.suredbits.com/testnet-chaindump-2-25-2020.zip), unzip it and put the file in your `$HOME/.bitcoin-s/testnet3` directory and then from there, run
To run your Bitcoin-S Server on testnet, simply change `network = testnet3` and change
your `peers = ["neutrino.testnet3.suredbits.com:18333"] ` in your `.bitcoin-s/bitcoin-s.conf` file.
This will allow you to connect to Suredbits' neutrino-enabled `bitcoind` node.
Keep in mind then when you restart your server, it will begin initial sync which will take
many hours as all block filters for all testnet blocks will be downloaded.
If you wish to speed this process up,
download [this snapshot](https://s3-us-west-2.amazonaws.com/www.suredbits.com/chaindb-testnet-2021-02-03.zip), unzip it and put the file in your `$HOME/.bitcoin-s/testnet3` directory and then from there, run
```bashrc
cat chaindump.sql | sqlite3 chaindb.sqlite
$ unzip chaindb-testnet-2021-02-03.zip
$ mv chaindb.sqlite ~/.bitcoin-s/testnet/
```
This should take a couple minutes to execute, but once it is done, you will only have a short while left to sync once you start your server.

View File

@ -79,7 +79,7 @@ libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-zmq" % "0.4.0"
You can also run on the bleeding edge of Bitcoin-S, by
adding a snapshot build to your `build.sbt`. The most
recent snapshot published is `0.4.0+282-4a131626+20210128-1145-SNAPSHOT`.
recent snapshot published is `0.5.0+10-6d898074-SNAPSHOT`.

View File

@ -32,14 +32,14 @@ import org.bitcoins.core.crypto._
//get 256 bits of random entropy
val entropy = MnemonicCode.getEntropy256Bits
// entropy: scodec.bits.BitVector = BitVector(256 bits, 0x9b4cf41b905f007e39056023325e547a988365f87b87f295fb0b1c951367ff94)
// entropy: scodec.bits.BitVector = BitVector(256 bits, 0xd1a544971d98b3c7f159720fd6fcdf7f66c04b4f17cb6473d68dcfcbef7e5daa)
val mnemonic = MnemonicCode.fromEntropy(entropy)
// mnemonic: MnemonicCode = Masked(MnemonicCodeImpl)
//you can print that mnemonic seed with this
println(mnemonic.words)
// Vector(opera, guilt, alone, camera, useless, disease, tomato, project, case, napkin, never, vivid, market, real, tiger, ill, verb, quit, security, decrease, eye, recycle, wrestle, other)
// Vector(spider, clay, chair, depth, menu, token, shell, comic, average, retire, daughter, yard, hire, certain, detail, west, good, pact, pet, panel, same, sand, issue, essence)
```
Now that we have a `MnemonicCode` that was securely generated, we need to now create `KeyManagerParams` which tells us how to generate
@ -60,7 +60,7 @@ Now we can construct a native segwit key manager for the regtest network!
//this will create a temp directory with the prefix 'key-manager-example` that will
//have a file in it called "encrypted-bitcoin-s-seed.json"
val seedPath = Files.createTempDirectory("key-manager-example").resolve(WalletStorage.ENCRYPTED_SEED_FILE_NAME)
// seedPath: Path = /tmp/key-manager-example7131164472328339657/encrypted-bitcoin-s-seed.json
// seedPath: Path = /tmp/key-manager-example4028585734646796477/encrypted-bitcoin-s-seed.json
//let's create a native segwit key manager
val purpose = HDPurposes.SegWit
@ -71,19 +71,19 @@ val network = RegTest
// network: RegTest.type = RegTest
val kmParams = KeyManagerParams(seedPath, purpose, network)
// kmParams: KeyManagerParams = KeyManagerParams(/tmp/key-manager-example7131164472328339657/encrypted-bitcoin-s-seed.json,m/84',RegTest)
// kmParams: KeyManagerParams = KeyManagerParams(/tmp/key-manager-example4028585734646796477/encrypted-bitcoin-s-seed.json,m/84',RegTest)
val aesPasswordOpt = Some(AesPassword.fromString("password"))
// aesPasswordOpt: Some[AesPassword] = Some(Masked(AesPassword))
val km = BIP39KeyManager.initializeWithMnemonic(aesPasswordOpt, mnemonic, None, kmParams)
// km: Either[KeyManagerInitializeError, BIP39KeyManager] = Right(org.bitcoins.keymanager.bip39.BIP39KeyManager@6b3b2623)
// km: Either[KeyManagerInitializeError, BIP39KeyManager] = Right(org.bitcoins.keymanager.bip39.BIP39KeyManager@3b9baec0)
val rootXPub = km.right.get.getRootXPub
// rootXPub: ExtPublicKey = vpub5SLqN2bLY4WeYrz59tnMAW2YHr98tGpfoDbNxbBJymFFUTCMkhUeBXus8nqncDLpJSDUMg9DZfu7KfLfSUUgY4GVRNhz7vQ3bJbnmc9jSf5
// rootXPub: ExtPublicKey = vpub5SLqN2bLY4WeaLzHXLaDFs2Hc3ZrNbkECR1HcFZ4Gg5dGkwQyd3FRyoyqtX4N7zQJtw3mEkRtaAVG36AySj4VK2AgoeQCyxeL5Mw12EjvEp
println(rootXPub)
// vpub5SLqN2bLY4WeYrz59tnMAW2YHr98tGpfoDbNxbBJymFFUTCMkhUeBXus8nqncDLpJSDUMg9DZfu7KfLfSUUgY4GVRNhz7vQ3bJbnmc9jSf5
// vpub5SLqN2bLY4WeaLzHXLaDFs2Hc3ZrNbkECR1HcFZ4Gg5dGkwQyd3FRyoyqtX4N7zQJtw3mEkRtaAVG36AySj4VK2AgoeQCyxeL5Mw12EjvEp
```
Which should print something that looks like this
@ -98,17 +98,17 @@ again after initializing it once. You can use the same `mnemonic` for different
```scala
//let's create a nested segwit key manager for mainnet
val mainnetKmParams = KeyManagerParams(seedPath, HDPurposes.SegWit, MainNet)
// mainnetKmParams: KeyManagerParams = KeyManagerParams(/tmp/key-manager-example7131164472328339657/encrypted-bitcoin-s-seed.json,m/84',MainNet)
// mainnetKmParams: KeyManagerParams = KeyManagerParams(/tmp/key-manager-example4028585734646796477/encrypted-bitcoin-s-seed.json,m/84',MainNet)
//we do not need to all `initializeWithMnemonic()` again as we have saved the seed to dis
val mainnetKeyManager = BIP39KeyManager.fromMnemonic(mnemonic, mainnetKmParams, None, Instant.now)
// mainnetKeyManager: BIP39KeyManager = org.bitcoins.keymanager.bip39.BIP39KeyManager@5a2293c7
// mainnetKeyManager: BIP39KeyManager = org.bitcoins.keymanager.bip39.BIP39KeyManager@61666178
val mainnetXpub = mainnetKeyManager.getRootXPub
// mainnetXpub: ExtPublicKey = zpub6jftahH18ngZx3kYVKvqzrQYyiiveknfTfgG6AkrVnkmgrTGmL8tfnYRDcg8bqxVvzghMaXTQKKJronvKG8jizzttjVgTZfzgCrNKt7sq9L
// mainnetXpub: ExtPublicKey = zpub6jftahH18ngZyXkkrmii6DQJHv9e95iDrs6Ajq8bnhb9VACKzFhVvESXviMQMkc5wTQGm98fjDagoBYRrEP7gFkaAAS6YdEbQycWZQaqHms
println(mainnetXpub)
// zpub6jftahH18ngZx3kYVKvqzrQYyiiveknfTfgG6AkrVnkmgrTGmL8tfnYRDcg8bqxVvzghMaXTQKKJronvKG8jizzttjVgTZfzgCrNKt7sq9L
// zpub6jftahH18ngZyXkkrmii6DQJHv9e95iDrs6Ajq8bnhb9VACKzFhVvESXviMQMkc5wTQGm98fjDagoBYRrEP7gFkaAAS6YdEbQycWZQaqHms
```
Which gives us something that looks like this

View File

@ -5,11 +5,11 @@ original_id: build-oracle-server
---
The Oracle Server is a DLC Oracle with functionality for creating events and attesting to them.
The Oracle Server is interactable through the RPC interface.
You can interact with the oracle server with `bitcoin-s-cli` or `curl`
The following a guide is for how to build the oracle server.
If you are looking for the documentation on how to use the oracle server,
checkout [this page](oracle-server.md)
checkout [this page](oracle-server.md).
## Step 1: Java and Scala
@ -83,6 +83,6 @@ You can also pass in a custom `rpcport` to bind to
./app/oracle-server/target/universal/stage/bin/bitcoin-s-oracle-server --rpcport 12345
```
For more information on configuring the server please see our [configuration](../config/configuration.md) document
For more information on configuring the server please see our [configuration](../config/configuration.md) document.
For more information on how to use our built in `cli` to interact with the server please see [cli.md](../applications/cli.md)
For more information on how to use our built in `cli` to interact with the server please see the [cli docs](../applications/cli.md).

View File

@ -5,18 +5,18 @@ original_id: oracle-server
---
The Oracle Server is a DLC Oracle with functionality for creating events and attesting to them.
The Oracle Server is interactable through the RPC interface.
You can interact with the oracle server with `bitcoin-s-cli` or `curl`
The following a guide is for interacting with the oracle
If you are looking for the documentation on how to build the oracle server,
checkout [this page](build-oracle-server.md)
checkout [this page](build-oracle-server.md).
## Server Endpoints
- `getpublickey` - Get oracle's public key
- `getstakingaddress` - Get oracle's staking address
- `listevents` - Lists all oracle announcement TLVs
- `createevent` `label` `maturationtime` `outcomes` - Registers an oracle event
- `createenumevent` `label` `maturationtime` `outcomes` - Registers an oracle enum event
- `label` - Label for this event
- `maturationtime` - The earliest expected time an outcome will be signed, given in epoch second
- `outcomes` - Possible outcomes for this event
@ -43,7 +43,7 @@ checkout [this page](build-oracle-server.md)
Bitcoin-S CLI:
```bash
$ bitcoin-s-cli createevent test 1701917137 "outcome1,outcome2,outcome3"
$ bitcoin-s-cli createenumevent test 1701917137 "outcome1,outcome2,outcome3"
fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374
$ bitcoin-s-cli getevent fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374
@ -77,7 +77,7 @@ fdd8687004746573745f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e521
CURL:
```bash
$ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "createevent", "params": ["testEvent", 1701917137, ["outcome1", "outcome2", "outcome3"]]}' -H "Content-Type: application/json" http://127.0.0.1:9999/
$ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "createenumevent", "params": ["testEvent", 1701917137, ["outcome1", "outcome2", "outcome3"]]}' -H "Content-Type: application/json" http://127.0.0.1:9999/
{"result":"fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374","error":null}
$ curl --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getevent", "params": ["fdd824b0ba0f08e9becbf77019e246ca8a80c027585634dc1aed4b7f67442ada394b40dcb242d8a8c84893a752b93f30ff07525b0604382255ec7392fcc6f230140feb905f6f49e116de8cb57856bacdd9997d8dfb73877f64a4ec8d45fc0e73a0e52115fdd8224c000180e550759cb6275f6db3fad2b616ed51bdcccc204d0d978cd921cafae9fc1d6f657131d1fdd8061d0003086f7574636f6d6531086f7574636f6d6532086f7574636f6d65330474657374"]}' -H "Content-Type: application/json" http://127.0.0.1:9999/

View File

@ -70,12 +70,12 @@ Here is an example of calling bouncy castle methods in `ECKey`
val privKey = ECPrivateKey.freshPrivateKey
// privKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
val publicKey = privKey.publicKeyWithBouncyCastle
// publicKey: ECPublicKey = ECPublicKey(02b967793f6d2af1a140d09a50da7bc79eab92302c6bc6726e3a35b6aa99abc8b2)
// publicKey: ECPublicKey = ECPublicKey(0322b9a4188a8b9541d8d4e6be9e418ff7ab44d8655cb63145703939e6a348ef43)
val dataToSign = DoubleSha256Digest.empty
// dataToSign: DoubleSha256Digest = DoubleSha256Digest(0000000000000000000000000000000000000000000000000000000000000000)
val signature = privKey.signWithBouncyCastle(dataToSign.bytes)
// signature: ECDigitalSignature = ECDigitalSignature(3044022010e33d10f53d6359662468321879d745940981648c252c6f862621087c7441b7022029c40ee3bad3116bb1a9027fd871df4247ef5b28007cda88eaf0535e66681676)
// signature: ECDigitalSignature = ECDigitalSignature(3045022100b24cc0a8e9f778899db470dce18b7902e87881343484fc7c0c32058f8a73ddff022027d0600df4a69a12ad03f5a23736be58fcdd4ca2c14b202ef9a643d1632fde6b)
val verified = publicKey.verifyWithBouncyCastle(dataToSign.bytes, signature)
// verified: Boolean = true

View File

@ -117,15 +117,7 @@ val keyManager = BIP39KeyManager.initialize(aesPasswordOpt, walletConfig.kmParam
val wallet = Wallet(keyManager, new NodeApi {
override def broadcastTransaction(tx: Transaction): Future[Unit] = Future.successful(())
override def downloadBlocks(blockHashes: Vector[DoubleSha256Digest]): Future[Unit] = Future.successful(())
}, new ChainQueryApi {
override def epochSecondToBlockHeight(time: Long): Future[Int] = Future.successful(0)
override def getBlockHeight(blockHash: DoubleSha256DigestBE): Future[Option[Int]] = Future.successful(None)
override def getBestBlockHash(): Future[DoubleSha256DigestBE] = Future.successful(DoubleSha256DigestBE.empty)
override def getNumberOfConfirmations(blockHashOpt: DoubleSha256DigestBE): Future[Option[Int]] = Future.successful(None)
override def getFilterCount: Future[Int] = Future.successful(0)
override def getHeightByBlockStamp(blockStamp: BlockStamp): Future[Int] = Future.successful(0)
override def getFiltersBetweenHeights(startHeight: Int, endHeight: Int): Future[Vector[FilterResponse]] = Future.successful(Vector.empty)
}, ConstantFeeRateProvider(SatoshisPerVirtualByte.one), creationTime = Instant.now)
}, chainApi, ConstantFeeRateProvider(SatoshisPerVirtualByte.one), creationTime = Instant.now)
val walletF: Future[WalletApi] = configF.flatMap { _ =>
Wallet.initialize(wallet,bip39PasswordOpt)
}

View File

@ -10,7 +10,8 @@
"Applications": [
"version-0.5.0-applications/cli",
"version-0.5.0-applications/server",
"version-0.5.0-applications/gui"
"version-0.5.0-applications/gui",
"version-0.5.0-applications/server-systemd"
],
"Chain": [
"version-0.5.0-chain/chain",