2021 05 07 fix getting setup (#3053)

* Fix getting-setup, add prodSettings,testSettings to new tor module

* Fix missing wallet rpc examples on 0.6
This commit is contained in:
Chris Stewart 2021-05-07 17:55:21 -05:00 committed by GitHub
parent 02c4505948
commit 97a854c5bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 170 additions and 68 deletions

View File

@ -149,10 +149,12 @@ lazy val lndRpc = project
lazy val tor = project
.in(file("tor"))
.settings(CommonSettings.prodSettings:_*)
.dependsOn(cryptoJVM)
lazy val torTest = project
.in(file("tor-test"))
.settings(CommonSettings.testSettings:_*)
.dependsOn(tor, testkit)
lazy val jsProjects: Vector[ProjectReference] =

View File

@ -109,10 +109,10 @@ https://oss.sonatype.org/content/repositories/snapshots/org/bitcoin-s/
## Building JARs yourself
Please see [getting-setup.md](getting-setup.md)
Please see [our setup docs](getting-setup.md)
## If you want to setup Bitcoin-S locally for development
Please see [getting-setup.md](getting-setup.md)
Please see [our setup docs](getting-setup.md)

View File

@ -44,7 +44,7 @@ class TorProtocolHandlerSpec
super.withFixture(test) // Invoke the test function
}
ignore("connect to real tor daemon") {
/* ignore("connect to real tor daemon") {
val promiseOnionAddress = Promise[InetSocketAddress]()
val protocolHandlerProps =
@ -61,7 +61,7 @@ class TorProtocolHandlerSpec
val address = Await.result(promiseOnionAddress.future, 30.seconds)
println(address)
}
}*/
test("happy path v2") {
val promiseOnionAddress = Promise[InetSocketAddress]()
@ -318,7 +318,7 @@ class TorProtocolHandlerSpec
"513 Invalid argument\r\n"
)
val t = intercept[TorException] {
intercept[TorException] {
Await.result(promiseOnionAddress.future, 3.seconds)
}

View File

@ -152,6 +152,9 @@
"wallet/wallet-rescan": {
"title": "Wallet Rescans"
},
"wallet/wallet-rpc": {
"title": "Wallet RPC Examples"
},
"wallet/wallet-sync": {
"title": "Wallet Sync"
},
@ -613,6 +616,96 @@
},
"version-0.5.0/wallet/version-0.5.0-wallet": {
"title": "Wallet"
},
"version-0.6.0/applications/version-0.6.0-server": {
"title": "Application Server"
},
"version-0.6.0/chain/version-0.6.0-filter-sync": {
"title": "Syncing Blockfilters"
},
"version-0.6.0/config/version-0.6.0-configuration title: Application Configuration": {
"title": "configuration title: Application Configuration"
},
"version-0.6.0/core/version-0.6.0-addresses": {
"title": "Generating Addresses"
},
"version-0.6.0/core/version-0.6.0-core-intro": {
"title": "Core Module"
},
"version-0.6.0/core/version-0.6.0-dlc": {
"title": "Discreet Log Contract Data Structures"
},
"version-0.6.0/core/version-0.6.0-hd-keys": {
"title": "HD Key Generation"
},
"version-0.6.0/core/version-0.6.0-psbts": {
"title": "Partially Signed Bitcoin Transactions"
},
"version-0.6.0/core/version-0.6.0-txbuilder": {
"title": "TxBuilder Example"
},
"version-0.6.0/crypto/version-0.6.0-adaptor-signatures": {
"title": "Adaptor Signatures"
},
"version-0.6.0/crypto/version-0.6.0-sign": {
"title": "Sign API"
},
"version-0.6.0/version-0.6.0-getting-setup": {
"title": "Getting Bitcoin-S installed on your machine"
},
"version-0.6.0/version-0.6.0-getting-started": {
"title": "Intro and Getting Started"
},
"version-0.6.0/key-manager/version-0.6.0-key-manager": {
"title": "Key Manager"
},
"version-0.6.0/node/version-0.6.0-node-api title: Node API": {
"title": "node-api title: Node API"
},
"version-0.6.0/node/version-0.6.0-node": {
"title": "Light Client"
},
"version-0.6.0/oracle-explorer-client/version-0.6.0-oracle-explorer-client": {
"title": "Oracle Explorer Client"
},
"version-0.6.0/oracle/version-0.6.0-build-oracle-server": {
"title": "Building the Oracle Server"
},
"version-0.6.0/oracle/version-0.6.0-oracle-election-example": {
"title": "Election Example"
},
"version-0.6.0/oracle/version-0.6.0-oracle-price-example": {
"title": "Price Example"
},
"version-0.6.0/oracle/version-0.6.0-oracle-server": {
"title": "Oracle Server"
},
"version-0.6.0/rpc/version-0.6.0-lnd-rpc": {
"title": "LND"
},
"version-0.6.0/rpc/version-0.6.0-rpc-clients-intro": {
"title": "Introduction"
},
"version-0.6.0/secp256k1/version-0.6.0-jni-modify": {
"title": "Adding to Secp256k1 JNI"
},
"version-0.6.0/secp256k1/version-0.6.0-secp256k1": {
"title": "Secp256k1"
},
"version-0.6.0/testkit/version-0.6.0-testkit-core": {
"title": "Testkit Core"
},
"version-0.6.0/testkit/version-0.6.0-testkit": {
"title": "Testkit"
},
"version-0.6.0/wallet/version-0.6.0-wallet-rescan": {
"title": "Wallet Rescans"
},
"version-0.6.0/wallet/version-0.6.0-wallet-rpc": {
"title": "Wallet RPC Examples"
},
"version-0.6.0/wallet/version-0.6.0-wallet": {
"title": "Wallet"
}
},
"links": {

View File

@ -165,6 +165,8 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
- `--sats ` - Display balance in satoshis
- `getunconfirmedbalance` `[options]` - Get the wallet balance of unconfirmed utxos
- `--sats ` - Display balance in satoshis
- `getbalances` `[options]` - Get the wallet balance by utxo state
- `--sats ` - Display balance in satoshis
- `getutxos` - Returns list of all wallet utxos
- `getaddresses` - Returns list of all wallet addresses currently being watched
- `getspentaddresses` - Returns list of all wallet addresses that have received funds and been spent
@ -176,6 +178,7 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
- `getaddressinfo` `address` - Returns list of all wallet accounts
- `address` - Address to get information about
- `getnewaddress` - Get a new address
- `listreservedutxos` - lists all utxos that are reserved in the wallet
- `sendtoaddress` `address` `amount` `[options]` - Send money to the given address
- `address` - Address to send to
- `amount` - Amount to send in BTC
@ -206,7 +209,7 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
- `txid` - The transaction id
- `lockunspent` `unlock` `transactions` - Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.
- `unlock` - Whether to unlock (true) or lock (false) the specified transactions
- `transactions` - The transaction outpoints to unlock/lock
- `transactions` - The transaction outpoints to unlock/lock, empty to apply to all utxos
- `importseed` `walletname` `words` `passphrase` - Imports a mnemonic seed as a new seed file
- `walletname` - Name to associate with this seed
- `words` - Mnemonic seed words, space separated
@ -246,6 +249,7 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
- `nrequired` - The number of required signatures out of the n keys.
- `keys` - The hex-encoded public keys.
- `address_type` -The address type to use. Options are "legacy", "p2sh-segwit", and "bech32"
- `estimatefee` - Returns the recommended fee rate using the fee provider
## Sign PSBT with Wallet Example

View File

@ -25,9 +25,9 @@ reason to keep using legacy transaction formats.
```scala
// this generates a random private key
val privkey = ECPrivateKey()
// privkey: ECPrivateKey = Masked(ECPrivateKeyImpl)
// privkey: ECPrivateKey = Masked(ECPrivateKey)
val pubkey = privkey.publicKey
// pubkey: org.bitcoins.crypto.ECPublicKey = ECPublicKey(02da06ea00abc1766e22267c3de60f8b878bee151640020e55b25e562364ee5d6e)
// pubkey: org.bitcoins.crypto.ECPublicKey = ECPublicKey(039c31dc6d0670e4b12f82d847daacd0cc0b1e7ce66b3e80abdb060521ae9e30f4)
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 = tb1qaa3rcp5yzpr8x0w6zusxh5aer6qztftljesshn
// segwitAddress: Bech32Address = tb1qj28h67naaccn0cyvxe6k4u93h5ff3k0ckc98j5
println(segwitAddress.toString)
// tb1qaa3rcp5yzpr8x0w6zusxh5aer6qztftljesshn
// tb1qj28h67naaccn0cyvxe6k4u93h5ff3k0ckc98j5
```
## 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 = n3LhUMPqUSjX1NPxLn7abU5WSmhJBiFHia
// legacyAddress: P2PKHAddress = mtstqvzTh5FzFaagX1bLTbFJjNAEyy24pj
println(legacyAddress.toString)
// n3LhUMPqUSjX1NPxLn7abU5WSmhJBiFHia
// mtstqvzTh5FzFaagX1bLTbFJjNAEyy24pj
```

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, 0x62eb2a698d651e1ce87cb4dde7444a6cfcb4ac152deb1fec7876def416566f81)
// entropy: BitVector = BitVector(256 bits, 0x0ccd701d5db70308c310ebfb7b27ebcde40bf581e997293510bd4a4806920134)
val mnemonicCode = MnemonicCode.fromEntropy(entropy)
// mnemonicCode: MnemonicCode = Masked(MnemonicCodeImpl)
mnemonicCode.words // the phrase the user should write down
// res0: Vector[String] = Vector(glass, flock, omit, bracket, faint, attack, peanut, notable, target, demand, barely, supreme, slender, figure, feed, runway, cable, glow, buffalo, sadness, door, clinic, safe, ceiling) // the phrase the user should write down
// res0: Vector[String] = Vector(art, high, also, rocket, ice, love, arrange, buddy, window, summer, wife, orange, doll, width, amateur, cream, circle, possible, consider, nest, lesson, empower, age, manual) // 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 = zpub6jftahH18ngZyJVkgvBx1MQEHkof9MxQ3y5baEPJDN2XzaxHXjuc5bRqzBn4jtaVnWBTeGSNAg3N5U3nqgtpCFcRrCNo9KaAsHZY2WEJUVG
// xpub: ExtPublicKey = zpub6jftahH18ngZy6WxEv5q1EzAtbQsuzZFYtZE2v8XRpp8ZiVTSDCfEyF8BaBiVMJTbmUJ79AUGga2ixQV1dCxBwgU374k6EhSFGc56kKd6Qi
// 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 = zpub6qrqaWTHWbosf4trAMe9sWVu5hE8a1Fr6nnewT1o7Vr5ca8WGWaVXfeo8b3EvGwk8Fap1wUx6pu2Zu9MTWjTZWh3ESsZ61j64LHekVGobrh
// accountXpub: ExtPublicKey = zpub6r6c18KMZEyQoRZmVAp3YDrGcLZNf7uadd4U2J1K27qBJrQdGvYMBoLqQucbwWay89FyWCTsk3r3oQgZC2WdrqDYWnUKNeRMymeT9SRUBLr
// address no. 0 ---------------┐
// external address ----------┐ |
@ -126,12 +126,12 @@ val firstAccountAddress = {
val scriptPubKey = P2WPKHWitnessSPKV0(pubkey)
Bech32Address(scriptPubKey, TestNet3)
}
// firstAccountAddress: Bech32Address = tb1qw8khnel5e070tpk9500um5t7qw7mesqhcwsu7y
// firstAccountAddress: Bech32Address = tb1qxa6adwt0lfer399shv220e9prn7ue4yc9m2nul
// tada! We just generated an address you can send money to,
// without having access to the private key!
firstAccountAddress.value
// res2: String = tb1qw8khnel5e070tpk9500um5t7qw7mesqhcwsu7y
// res2: String = tb1qxa6adwt0lfer399shv220e9prn7ue4yc9m2nul
// you can now continue deriving addresses from the same public
// key, by imitating what we did above. To get the next

View File

@ -85,10 +85,10 @@ val psbtWithSigHashFlags = psbtWithUpdatedSecondInput
// correctly in an application
// Here we use the relevant private keys to sign the first input
val privKey0 = ECPrivateKeyUtil.fromWIFToPrivateKey(
"cP53pDbR5WtAD8dYAW9hhTjuvvTVaEiQBdrz9XPrgLBeRFiyCbQr")
"cP53pDbR5WtAD8dYAW9hhTjuvvTVaEiQBdrz9XPrgLBeRFiyCbQr").toPrivateKey
val privKey1 = ECPrivateKeyUtil.fromWIFToPrivateKey(
"cR6SXDoyfQrcp4piaiHE97Rsgta9mNhGTen9XeonVgwsh4iSgw6d")
"cR6SXDoyfQrcp4piaiHE97Rsgta9mNhGTen9XeonVgwsh4iSgw6d").toPrivateKey
val psbtFirstSig =
psbtWithSigHashFlags

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@6be04fea[Running, parallelism = 16, size = 1, active = 0, running = 0, steals = 5740, tasks = 0, submissions = 0]
// ec: ExecutionContext = scala.concurrent.impl.ExecutionContextImpl$$anon$3@700ecef1[Running, parallelism = 8, size = 1, active = 0, running = 0, steals = 5740, tasks = 0, submissions = 0]
// Initialize a transaction builder
val builder = RawTxBuilder()
@ -17,25 +17,25 @@ val builder = RawTxBuilder()
// generate a fresh private key that we are going to use in the scriptpubkey
val privKey = ECPrivateKey.freshPrivateKey
// privKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
// privKey: ECPrivateKey = Masked(ECPrivateKey)
val pubKey = privKey.publicKey
// pubKey: ECPublicKey = ECPublicKey(0221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f)
// pubKey: ECPublicKey = ECPublicKey(032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7)
// 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(406d36ed4b1da94e4b97f25312ca620df99672fd)
// creditingSpk: P2PKHScriptPubKey = pkh(83a08518463b0a70a57af7466145614dc7fc1b79)
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(406d36ed4b1da94e4b97f25312ca620df99672fd))
// utxo: TransactionOutput = TransactionOutput(10000 sats,pkh(83a08518463b0a70a57af7466145614dc7fc1b79))
// the private key that locks the funds for the script we are spending too
val destinationPrivKey = ECPrivateKey.freshPrivateKey
// destinationPrivKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
// destinationPrivKey: ECPrivateKey = Masked(ECPrivateKey)
// the amount we are sending -- 5000 satoshis -- to the destinationSPK
val destinationAmount = 5000.satoshis
@ -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(3ebbbb7b65ea2e7b7383c4902e8e81ed74d3a5f6)
// destinationSPK: P2PKHScriptPubKey = pkh(8c34a339f657131292465c908cd9332deecee097)
// 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(3ebbbb7b65ea2e7b7383c4902e8e81ed74d3a5f6)))
// destinations: Vector[TransactionOutput] = Vector(TransactionOutput(5000 sats,pkh(8c34a339f657131292465c908cd9332deecee097)))
// 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(406d36ed4b1da94e4b97f25312ca620df99672fd))),UInt32Impl(0))
// creditingTx: BaseTransaction = BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(83a08518463b0a70a57af7466145614dc7fc1b79))),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(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0)
// outPoint: TransactionOutPoint = TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0)
val input = TransactionInput(
outPoint,
EmptyScriptSignature,
sequenceNumber = UInt32.zero)
// input: TransactionInput = TransactionInputImpl(TransactionOutPoint(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),EmptyScriptSignature,UInt32Impl(0))
// input: TransactionInput = TransactionInputImpl(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a: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(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(3ebbbb7b65ea2e7b7383c4902e8e81ed74d3a5f6))),UInt32Impl(0))
// builderResult: RawTxBuilderResult = RawTxBuilderResult(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(8c34a339f657131292465c908cd9332deecee097))),UInt32Impl(0))
// this contains the information needed to analyze our input during finalization
val inputInfo = P2PKHInputInfo(outPoint, amount, privKey.publicKey)
// inputInfo: P2PKHInputInfo = P2PKHInputInfo(TransactionOutPoint(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),10000 sats,ECPublicKey(0221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f))
// inputInfo: P2PKHInputInfo = P2PKHInputInfo(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),10000 sats,ECPublicKey(032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7))
// 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
@ -98,20 +98,20 @@ val feeRate = SatoshisPerByte(1.satoshi)
// feeRate: SatoshisPerByte = 1 sats/byte
val changePrivKey = ECPrivateKey.freshPrivateKey
// changePrivKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
// changePrivKey: ECPrivateKey = Masked(ECPrivateKey)
val changeSPK = P2PKHScriptPubKey(pubKey = changePrivKey.publicKey)
// changeSPK: P2PKHScriptPubKey = pkh(19b08251ccd72e7d17f52c1a2006e177ff74cae4)
// changeSPK: P2PKHScriptPubKey = pkh(a0bd7fb5d33e97066745034f269c74f435990da8)
// 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(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),10000 sats,ECPublicKey(0221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f))),1 sats/byte,pkh(19b08251ccd72e7d17f52c1a2006e177ff74cae4))
// finalizer: StandardNonInteractiveFinalizer = StandardNonInteractiveFinalizer(Vector(P2PKHInputInfo(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),10000 sats,ECPublicKey(032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7))),1 sats/byte,pkh(a0bd7fb5d33e97066745034f269c74f435990da8))
// We can now finalize the tx builder result from earlier with this finalizer
val unsignedTx: Transaction = finalizer.buildTx(builderResult)
// unsignedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(3ebbbb7b65ea2e7b7383c4902e8e81ed74d3a5f6)), TransactionOutput(4775 sats,pkh(19b08251ccd72e7d17f52c1a2006e177ff74cae4))),UInt32Impl(0))
// unsignedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),EmptyScriptSignature,UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(8c34a339f657131292465c908cd9332deecee097)), TransactionOutput(4775 sats,pkh(a0bd7fb5d33e97066745034f269c74f435990da8))),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(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),10000 sats,ECPublicKey(0221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(406d36ed4b1da94e4b97f25312ca620df99672fd))),UInt32Impl(0)),Vector(Masked(ECPrivateKeyImpl)),SIGHASH_ALL(Int32Impl(1)))
// utxoInfo: ScriptSignatureParams[P2PKHInputInfo] = ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),10000 sats,ECPublicKey(032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(83a08518463b0a70a57af7466145614dc7fc1b79))),UInt32Impl(0)),Vector(Masked(ECPrivateKey)),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(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),10000 sats,ECPublicKey(0221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(406d36ed4b1da94e4b97f25312ca620df99672fd))),UInt32Impl(0)),Vector(Masked(ECPrivateKeyImpl)),SIGHASH_ALL(Int32Impl(1))))
// utxoInfos: Vector[ScriptSignatureParams[InputInfo]] = Vector(ScriptSignatureParams(P2PKHInputInfo(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),10000 sats,ECPublicKey(032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7)),BaseTransaction(Int32Impl(1),Vector(),Vector(TransactionOutput(10000 sats,pkh(83a08518463b0a70a57af7466145614dc7fc1b79))),UInt32Impl(0)),Vector(Masked(ECPrivateKey)),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
@ -142,7 +142,7 @@ val signedTx: Transaction =
utxoInfos = utxoInfos,
expectedFeeRate = feeRate
)
// signedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(e42c4919ec52597b2a8bca5f691bb551febc4ed5d5185ea56405c4e423077cf6:0),P2PKHScriptSignature(ECPublicKey(0221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f), ECDigitalSignature(3044022019a959074d916270112980a8ab6d1835d6ff04121a4b1a82bac4a5e4121c720e022027ed31d51f4713bc8901f0d39d70ef4c85712726e522005f232b70d5eabe170d01)),UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(3ebbbb7b65ea2e7b7383c4902e8e81ed74d3a5f6)), TransactionOutput(4775 sats,pkh(19b08251ccd72e7d17f52c1a2006e177ff74cae4))),UInt32Impl(0))
// signedTx: Transaction = BaseTransaction(Int32Impl(2),Vector(TransactionInputImpl(TransactionOutPoint(811f6e83a9b9238fd413b2c6c0f7a83511664b169f349c018d170f84646ef39a:0),P2PKHScriptSignature(ECPublicKeyBytes(ByteVector(33 bytes, 0x032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7)), ECDigitalSignature(3044022073c88e12b1d924aab370b63fc5e808a794ed41066b233fa96eb3efa03462dda702206a04bbe23e98a20cef1eb5c8b36c0034dfff7d215d340ce65fb6b6f49b04cd1e01)),UInt32Impl(0))),Vector(TransactionOutput(5000 sats,pkh(8c34a339f657131292465c908cd9332deecee097)), TransactionOutput(4775 sats,pkh(a0bd7fb5d33e97066745034f269c74f435990da8))),UInt32Impl(0))
```
```scala
@ -154,5 +154,5 @@ signedTx.outputs.length
//remember, you can call .hex on any bitcoin-s data structure to get the hex representation!
signedTx.hex
// res4: String = 0200000001f67c0723e4c40564a55e18d5d54ebcfe51b51b695fca8b2a7b5952ec19492ce4000000006a473044022019a959074d916270112980a8ab6d1835d6ff04121a4b1a82bac4a5e4121c720e022027ed31d51f4713bc8901f0d39d70ef4c85712726e522005f232b70d5eabe170d01210221a0372e832444037fae5a633b1011f977de38d8dbf15ee86f9792f128bbf69f000000000288130000000000001976a9143ebbbb7b65ea2e7b7383c4902e8e81ed74d3a5f688aca7120000000000001976a91419b08251ccd72e7d17f52c1a2006e177ff74cae488ac00000000
// res4: String = 02000000019af36e64840f178d019c349f164b661135a8f7c0c6b213d48f23b9a9836e1f81000000006a473044022073c88e12b1d924aab370b63fc5e808a794ed41066b233fa96eb3efa03462dda702206a04bbe23e98a20cef1eb5c8b36c0034dfff7d215d340ce65fb6b6f49b04cd1e0121032fda2d352b5baee87f99d1f2317f6070ebf06c51c2d5d03682a9ca5cbcce9af7000000000288130000000000001976a9148c34a339f657131292465c908cd9332deecee09788aca7120000000000001976a914a0bd7fb5d33e97066745034f269c74f435990da888ac00000000
```

View File

@ -51,13 +51,13 @@ val extPrivKey = ExtPrivateKey(ExtKeyVersion.SegWitMainNetPriv)
// extPrivKey: ExtPrivateKey = Masked(ExtPrivateKeyImpl)
extPrivKey.sign(DoubleSha256Digest.empty.bytes)
// res0: ECDigitalSignature = ECDigitalSignature(30440220544800a9006f156b21db20dc177fba4e087ed699ff8d388e23223d5821e3490102205321f3059b3edd7fbb97952f1776e7d779686c89ada0b134be5d581c8f736a75)
// res0: ECDigitalSignature = ECDigitalSignature(304402206769b3e4d2cfd0328553bb8f5f791db7872e5bd0d06a153f516a42ab0baffe5e02200fb307a21f1cc3114d4cc255ed0a6295ead88677f92fcc7174f5ae8e1cbc4a83)
val path = BIP32Path(Vector(BIP32Node(0,false)))
// path: BIP32Path = m/0
extPrivKey.sign(DoubleSha256Digest.empty.bytes,path)
// res1: ECDigitalSignature = ECDigitalSignature(304402207c09b230d45a9afe8d4dc0a0ee3aa5a74c31a6d3e32f7b32dab99dee6762071d02207ff2ec0ed643f31b86902adfd66c2aa61c8fecf36271c6d6df6cc17264cbb603)
// res1: ECDigitalSignature = ECDigitalSignature(304402207f78eb87f9f1db14092a386c8f7465b7193a1eba5da0d01fbf17c1280dcf69cc0220191e416a90a315809c1c773c98da6a769948f08cfa6309db38b8f02eb333a52f)
```
With `ExtSign`, you can use `ExtPrivateKey` to sign transactions inside of `TxBuilder` since `UTXOSpendingInfo` takes in `Sign` as a parameter.

View File

@ -82,7 +82,7 @@ libraryDependencies += "org.bitcoin-s" %% "bitcoin-s-zmq" % "0.5.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.5.0-190-ca06b80e-20210428-0903-SNAPSHOT`.
recent snapshot published is `0.0.0-2781-02c45059-20210507-1710-SNAPSHOT`.
@ -105,10 +105,10 @@ https://oss.sonatype.org/content/repositories/snapshots/org/bitcoin-s/
## Building JARs yourself
Please see [getting-setup.md](getting-setup.md)
Please see [our setup docs](getting-setup)
## If you want to setup Bitcoin-S locally for development
Please see [getting-setup.md](getting-setup.md)
Please see [our setup docs](getting-setup)

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, 0x6d0fa037c7072ead6caae2079da51b1fffa9d32132bb7d2291bd41e76f416226)
// entropy: scodec.bits.BitVector = BitVector(256 bits, 0xec03eedae230b4b26daac4533696c2f0c2e3d7159ef9e6ace82078c0632e6e69)
val mnemonic = MnemonicCode.fromEntropy(entropy)
// mnemonic: MnemonicCode = Masked(MnemonicCodeImpl)
//you can print that mnemonic seed with this
println(mnemonic.words)
// Vector(home, laptop, assume, mix, indicate, find, razor, fox, always, unfold, egg, divide, whisper, trumpet, luggage, first, large, behind, hungry, long, ivory, pass, mass, scan)
// Vector(ugly, buyer, repeat, settle, area, float, repeat, flat, farm, regret, radar, thunder, comfort, twist, filter, tennis, trade, guard, amount, various, alert, now, rifle, crack)
```
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-example1457373026665946247/encrypted-bitcoin-s-seed.json
// seedPath: Path = /var/folders/fg/scntn26d4h55x96zc456l0r40000gn/T/key-manager-example1996746280318875131/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-example1457373026665946247/encrypted-bitcoin-s-seed.json,m/84',RegTest)
// kmParams: KeyManagerParams = KeyManagerParams(/var/folders/fg/scntn26d4h55x96zc456l0r40000gn/T/key-manager-example1996746280318875131/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@4e5027f)
// km: Either[KeyManagerInitializeError, BIP39KeyManager] = Right(org.bitcoins.keymanager.bip39.BIP39KeyManager@66e21918)
val rootXPub = km.right.get.getRootXPub
// rootXPub: ExtPublicKey = vpub5SLqN2bLY4WeZbx48czziTwoGPgTy15QtbiWN74GPP7VnFLciSuw8bikepNv7dvvEaoHbPtBh9r4a13t7Mv81Af3YD4QKh6Whyiow4LDkjd
// rootXPub: ExtPublicKey = vpub5SLqN2bLY4WeZVryo58y9pEmbBvrgP7PhBXJk1JZVJD7WEdM1d3C88EfqNV1p3nKEu61bpmTaVKnr2unRxrQkTPUYUGKEYsWLTnx3Yxvosj
println(rootXPub)
// vpub5SLqN2bLY4WeZbx48czziTwoGPgTy15QtbiWN74GPP7VnFLciSuw8bikepNv7dvvEaoHbPtBh9r4a13t7Mv81Af3YD4QKh6Whyiow4LDkjd
// vpub5SLqN2bLY4WeZVryo58y9pEmbBvrgP7PhBXJk1JZVJD7WEdM1d3C88EfqNV1p3nKEu61bpmTaVKnr2unRxrQkTPUYUGKEYsWLTnx3Yxvosj
```
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-example1457373026665946247/encrypted-bitcoin-s-seed.json,m/84',MainNet)
// mainnetKmParams: KeyManagerParams = KeyManagerParams(/var/folders/fg/scntn26d4h55x96zc456l0r40000gn/T/key-manager-example1996746280318875131/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@29fa05a
// mainnetKeyManager: BIP39KeyManager = org.bitcoins.keymanager.bip39.BIP39KeyManager@4a04af70
val mainnetXpub = mainnetKeyManager.getRootXPub
// mainnetXpub: ExtPublicKey = zpub6jftahH18ngZxniXU49VYpKoxGGFjV3QZ3oPVgdouQd1zebXj5aBcrMJjeDG7GYbs9GWbJGRXoGG79W8z9aBC7PT1Zr6fLNTnsyPVMtiBuF
// mainnetXpub: ExtPublicKey = zpub6jftahH18ngZxgdT8WHTzAcnH4WeSs5PMdcBsat71KididtG2FhScNsDvCKMogPzsTZEbj9hR8jzPBN3JkWTwQ7t1q41aC9TRN3XbszCLSr
println(mainnetXpub)
// zpub6jftahH18ngZxniXU49VYpKoxGGFjV3QZ3oPVgdouQd1zebXj5aBcrMJjeDG7GYbs9GWbJGRXoGG79W8z9aBC7PT1Zr6fLNTnsyPVMtiBuF
// zpub6jftahH18ngZxgdT8WHTzAcnH4WeSs5PMdcBsat71KididtG2FhScNsDvCKMogPzsTZEbj9hR8jzPBN3JkWTwQ7t1q41aC9TRN3XbszCLSr
```
Which gives us something that looks like this

View File

@ -68,16 +68,16 @@ Here is an example of calling bouncy castle methods in `ECKey`
```scala
val privKey = ECPrivateKey.freshPrivateKey
// privKey: ECPrivateKey = Masked(ECPrivateKeyImpl)
// privKey: ECPrivateKey = Masked(ECPrivateKey)
// calls bouncy castle indirectly via CryptoContext
val publicKey = privKey.publicKey
// publicKey: ECPublicKey = ECPublicKey(0393d4b6b67065c1b536f0015c729df1fc97fbe1f25115e2426ad220a4268dac39)
// publicKey: ECPublicKey = ECPublicKey(02b0d8755575c0c507aec37de8a49ffa3aac059d2a5defb489b1b25e3a4bdf8da1)
val dataToSign = DoubleSha256Digest.empty
// dataToSign: DoubleSha256Digest = DoubleSha256Digest(0000000000000000000000000000000000000000000000000000000000000000)
// calls bouncy castle indirectly via CryptoContext
val signature = privKey.sign(dataToSign.bytes)
// signature: ECDigitalSignature = ECDigitalSignature(30440220445169f62426fed42ed12a5e9861dad034e86da1e71f1a069ff7709a69603d1e0220651b2a4937673d3e908e690e90a458e46dffaefcc899ae32aaacd76133ffec2d)
// signature: ECDigitalSignature = ECDigitalSignature(3044022071b183533330f988f55ab6a6444d4c35070e805941a8ce1b0b18a5e93bec15a102202e644ef01026416828890dbf20bf43c906cde677be8df3bc22c4dd910a43708f)
// calls bouncy castle indirectly via CryptoContext
val verified = publicKey.verify(dataToSign.bytes, signature)