Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbaad04f24 | ||
|
|
64b9646870 | ||
|
|
e672875394 | ||
|
|
e639914d22 | ||
|
|
836f2b4263 | ||
|
|
85b1b92b6d | ||
|
|
d8b66641b3 | ||
|
|
3bb3b9f397 | ||
|
|
29fc067696 | ||
|
|
94f0ae85e3 | ||
|
|
ffa5ad7c28 | ||
|
|
d9e8a13cde | ||
|
|
d67e9758c7 | ||
|
|
079d83d887 | ||
|
|
ca4c9ca64c | ||
|
|
31ab9bfc03 | ||
|
|
de0259a820 | ||
|
|
faf3645361 | ||
|
|
b2d3a2cf30 | ||
|
|
732df83346 | ||
|
|
b7e7d879b3 | ||
|
|
9368124513 | ||
|
|
71b2eff813 | ||
|
|
4b7c49d92d | ||
|
|
74756ed597 | ||
|
|
5e91c83e0a | ||
|
|
51792c3528 | ||
|
|
c34ccdbeb9 | ||
|
|
0bdf6beda1 | ||
|
|
7484b84589 | ||
|
|
7727a62ae6 | ||
|
|
a8a9b63d33 |
@ -1,16 +1,14 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "6"
|
- "lts/*"
|
||||||
- "7"
|
|
||||||
- "8"
|
|
||||||
- "9"
|
- "9"
|
||||||
- "10"
|
- "10"
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- node_js: "6"
|
- node_js: "lts/*"
|
||||||
env: TEST_SUITE=standard
|
env: TEST_SUITE=standard
|
||||||
- node_js: "6"
|
- node_js: "lts/*"
|
||||||
env: TEST_SUITE=coverage
|
env: TEST_SUITE=coverage
|
||||||
env:
|
env:
|
||||||
- TEST_SUITE=unit
|
- TEST_SUITE=unit
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
|
# 4.0.1
|
||||||
|
__fixed__
|
||||||
|
- Fixed `tiny-secp256k1` dependency version (used `ecurve`) (#1139)
|
||||||
|
- Fixed `TransactionBuilder` throwing when trying to sign `P2WSH(P2WPKH)` (#1135)
|
||||||
|
|
||||||
# 4.0.0
|
# 4.0.0
|
||||||
__added__
|
__added__
|
||||||
- Added [`bip32`](https://github.com/bitcoinjs/bip32) dependency as a primary export (#1073)
|
- Added [`bip32`](https://github.com/bitcoinjs/bip32) dependency as a primary export (#1073)
|
||||||
@ -21,12 +26,13 @@ __removed__
|
|||||||
- Removed `ECPair.prototype.getAddress`, use `payments.p2pkh` instead (#1085)
|
- Removed `ECPair.prototype.getAddress`, use `payments.p2pkh` instead (#1085)
|
||||||
- Removed `ECPair.prototype.getPrivateKey`, use `ECPair.prototype.privateKey` property (#1070)
|
- Removed `ECPair.prototype.getPrivateKey`, use `ECPair.prototype.privateKey` property (#1070)
|
||||||
- Removed `ECPair.prototype.getPublicKey`, use `ECPair.prototype.publicKey` property (#1070)
|
- Removed `ECPair.prototype.getPublicKey`, use `ECPair.prototype.publicKey` property (#1070)
|
||||||
|
- Removed `ECPair.prototype.getNetwork`, use `ECPair.prototype.network` property (#1070)
|
||||||
- Removed `ECSignature`, use `script.signature.encode/decode` instead (#459)
|
- Removed `ECSignature`, use `script.signature.encode/decode` instead (#459)
|
||||||
- Removed `HDNode`, use `bip32` export instead (#1073)
|
- Removed `HDNode`, use `bip32` export instead (#1073)
|
||||||
- Removed `bufferutils` (#1035)
|
- Removed `bufferutils` (#1035)
|
||||||
- Removed `networks.litecoin`, BYO non-Bitcoin networks instead (#1095)
|
- Removed `networks.litecoin`, BYO non-Bitcoin networks instead (#1095)
|
||||||
- Removed `script.isCanonicalSignature`, use `script.isCanonicalScriptSignature` instead (#1094)
|
- Removed `script.isCanonicalSignature`, use `script.isCanonicalScriptSignature` instead (#1094)
|
||||||
- Removed `script.*.input/output/check` functions (`templates`) (previously added in #681, #682) (#1119)
|
- Removed `script.*.input/output/check` functions (`templates`), use `payments.*` instead (`templates` previously added in #681, #682) (#1119)
|
||||||
- Removed dependency `bigi`, uses `bn.js` internally now (via `tiny-secp256k1`) (#1070, #1112)
|
- Removed dependency `bigi`, uses `bn.js` internally now (via `tiny-secp256k1`) (#1070, #1112)
|
||||||
- Removed public access to `ECPair` constructor, use exported functions `ECPair.fromPrivateKey`, `ECPair.fromWIF`, `ECPair.makeRandom`, or `ECPair.fromPublicKey` (#1070)
|
- Removed public access to `ECPair` constructor, use exported functions `ECPair.fromPrivateKey`, `ECPair.fromWIF`, `ECPair.makeRandom`, or `ECPair.fromPublicKey` (#1070)
|
||||||
|
|
||||||
|
|||||||
75
README.md
75
README.md
@ -27,7 +27,7 @@ Mistakes and bugs happen, but with your help in resolving and reporting [issues]
|
|||||||
- Friendly, with a strong and helpful community, ready to answer questions.
|
- Friendly, with a strong and helpful community, ready to answer questions.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
Presently, we do not have any formal documentation other than our [examples](#Examples), please [ask for help](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new) if our examples aren't enough to guide you.
|
Presently, we do not have any formal documentation other than our [examples](#examples), please [ask for help](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new) if our examples aren't enough to guide you.
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
@ -82,42 +82,45 @@ The below examples are implemented as integration tests, they should be very eas
|
|||||||
Otherwise, pull requests are appreciated.
|
Otherwise, pull requests are appreciated.
|
||||||
Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
|
Some examples interact (via HTTPS) with a 3rd Party Blockchain Provider (3PBP).
|
||||||
|
|
||||||
- [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L30)
|
- [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L22)
|
||||||
- [Generate an address from a SHA256 hash](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L37)
|
- [Generate an address from a SHA256 hash](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L29)
|
||||||
- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L48)
|
- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L40)
|
||||||
- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L55)
|
- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L47)
|
||||||
- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L69)
|
- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L60)
|
||||||
- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L78)
|
- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L67)
|
||||||
- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L88)
|
- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L76)
|
||||||
- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L103)
|
- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L90)
|
||||||
- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L117)
|
- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L104)
|
||||||
- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L136)
|
- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L123)
|
||||||
- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L146)
|
- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L133)
|
||||||
- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L21)
|
- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L13)
|
||||||
- [Create a 2-to-2 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L36)
|
- [Create a 2-to-2 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L28)
|
||||||
- [Create (and broadcast via 3PBP) a typical Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L55)
|
- [Create (and broadcast via 3PBP) a typical Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L47)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L87)
|
- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L83)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L109)
|
- [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L105)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L149)
|
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L143)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L184)
|
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2WPKH input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L174)
|
||||||
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L17)
|
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2PK input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L218)
|
||||||
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L24)
|
- [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L263)
|
||||||
- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L35)
|
- [Verify a Transaction signature](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L304)
|
||||||
- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L44)
|
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L12)
|
||||||
- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L59)
|
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L20)
|
||||||
- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L75)
|
- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L31)
|
||||||
- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L92)
|
- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L40)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L42)
|
- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L55)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L83)
|
- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L71)
|
||||||
- [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L135)
|
- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L86)
|
||||||
- [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L177)
|
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L43)
|
||||||
|
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L88)
|
||||||
|
- [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L144)
|
||||||
|
- [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L190)
|
||||||
- [Recover a private key from duplicate R values](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L14)
|
- [Recover a private key from duplicate R values](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L14)
|
||||||
- [Recover a BIP32 parent private key from the parent public key, and a derived, non-hardened child private key](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L73)
|
- [Recover a BIP32 parent private key from the parent public key, and a derived, non-hardened child private key](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68)
|
||||||
- [Generate a single-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L75)
|
- [Generate a single-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L72)
|
||||||
- [Generate a single-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L94)
|
- [Generate a single-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L91)
|
||||||
- [Recover parent recipient.d, if a derived private key is leaked (and nonce was revealed)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L110)
|
- [Recover parent recipient.d, if a derived private key is leaked (and nonce was revealed)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L107)
|
||||||
- [Generate a dual-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L127)
|
- [Generate a dual-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L124)
|
||||||
- [Generate a dual-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L150)
|
- [Generate a dual-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L147)
|
||||||
|
|
||||||
If you have a use case that you feel could be listed here, please [ask for it](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new)!
|
If you have a use case that you feel could be listed here, please [ask for it](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new)!
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "bitcoinjs-lib",
|
"name": "bitcoinjs-lib",
|
||||||
"version": "3.3.2",
|
"version": "4.0.1",
|
||||||
"description": "Client-side Bitcoin JavaScript library",
|
"description": "Client-side Bitcoin JavaScript library",
|
||||||
"main": "./src/index.js",
|
"main": "./src/index.js",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0.0"
|
"node": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bitcoinjs",
|
"bitcoinjs",
|
||||||
@ -31,7 +31,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bech32": "^1.1.2",
|
"bech32": "^1.1.2",
|
||||||
"bip32": "^0.1.0",
|
"bip32": "^1.0.0",
|
||||||
"bip66": "^1.1.0",
|
"bip66": "^1.1.0",
|
||||||
"bitcoin-ops": "^1.4.0",
|
"bitcoin-ops": "^1.4.0",
|
||||||
"bs58check": "^2.0.0",
|
"bs58check": "^2.0.0",
|
||||||
@ -41,7 +41,7 @@
|
|||||||
"pushdata-bitcoin": "^1.0.1",
|
"pushdata-bitcoin": "^1.0.1",
|
||||||
"randombytes": "^2.0.1",
|
"randombytes": "^2.0.1",
|
||||||
"safe-buffer": "^5.1.1",
|
"safe-buffer": "^5.1.1",
|
||||||
"tiny-secp256k1": "^0.2.2",
|
"tiny-secp256k1": "^1.0.0",
|
||||||
"typeforce": "^1.11.3",
|
"typeforce": "^1.11.3",
|
||||||
"varuint-bitcoin": "^1.0.4",
|
"varuint-bitcoin": "^1.0.4",
|
||||||
"wif": "^2.0.1"
|
"wif": "^2.0.1"
|
||||||
|
|||||||
@ -5,9 +5,6 @@ const types = require('./types')
|
|||||||
const wif = require('wif')
|
const wif = require('wif')
|
||||||
|
|
||||||
const NETWORKS = require('./networks')
|
const NETWORKS = require('./networks')
|
||||||
|
|
||||||
// TODO: why is the function name toJSON weird?
|
|
||||||
function isPoint (x) { return ecc.isPoint(x) }
|
|
||||||
const isOptions = typeforce.maybe(typeforce.compile({
|
const isOptions = typeforce.maybe(typeforce.compile({
|
||||||
compressed: types.maybe(types.Boolean),
|
compressed: types.maybe(types.Boolean),
|
||||||
network: types.maybe(types.Network)
|
network: types.maybe(types.Network)
|
||||||
@ -57,7 +54,7 @@ function fromPrivateKey (buffer, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fromPublicKey (buffer, options) {
|
function fromPublicKey (buffer, options) {
|
||||||
typeforce(isPoint, buffer)
|
typeforce(ecc.isPoint, buffer)
|
||||||
typeforce(isOptions, options)
|
typeforce(isOptions, options)
|
||||||
return new ECPair(null, buffer, options)
|
return new ECPair(null, buffer, options)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -232,18 +232,21 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
|
|||||||
expanded.signatures = input.signatures
|
expanded.signatures = input.signatures
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let signScript = witnessScript
|
||||||
|
if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2SH(P2WSH(P2WPKH)) is a consensus failure')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
redeemScript: redeemScript,
|
redeemScript,
|
||||||
redeemScriptType: SCRIPT_TYPES.P2WSH,
|
redeemScriptType: SCRIPT_TYPES.P2WSH,
|
||||||
|
|
||||||
witnessScript: witnessScript,
|
witnessScript,
|
||||||
witnessScriptType: expanded.type,
|
witnessScriptType: expanded.type,
|
||||||
|
|
||||||
prevOutType: SCRIPT_TYPES.P2SH,
|
prevOutType: SCRIPT_TYPES.P2SH,
|
||||||
prevOutScript: p2sh.output,
|
prevOutScript: p2sh.output,
|
||||||
|
|
||||||
hasWitness: true,
|
hasWitness: true,
|
||||||
signScript: witnessScript,
|
signScript,
|
||||||
signType: expanded.type,
|
signType: expanded.type,
|
||||||
|
|
||||||
pubkeys: expanded.pubkeys,
|
pubkeys: expanded.pubkeys,
|
||||||
@ -274,14 +277,14 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
redeemScript: redeemScript,
|
redeemScript,
|
||||||
redeemScriptType: expanded.type,
|
redeemScriptType: expanded.type,
|
||||||
|
|
||||||
prevOutType: SCRIPT_TYPES.P2SH,
|
prevOutType: SCRIPT_TYPES.P2SH,
|
||||||
prevOutScript: p2sh.output,
|
prevOutScript: p2sh.output,
|
||||||
|
|
||||||
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
|
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
|
||||||
signScript: signScript,
|
signScript,
|
||||||
signType: expanded.type,
|
signType: expanded.type,
|
||||||
|
|
||||||
pubkeys: expanded.pubkeys,
|
pubkeys: expanded.pubkeys,
|
||||||
@ -303,15 +306,18 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
|
|||||||
expanded.signatures = input.signatures
|
expanded.signatures = input.signatures
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let signScript = witnessScript
|
||||||
|
if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2WSH(P2WPKH) is a consensus failure')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
witnessScript: witnessScript,
|
witnessScript,
|
||||||
witnessScriptType: expanded.type,
|
witnessScriptType: expanded.type,
|
||||||
|
|
||||||
prevOutType: SCRIPT_TYPES.P2WSH,
|
prevOutType: SCRIPT_TYPES.P2WSH,
|
||||||
prevOutScript: p2wsh.output,
|
prevOutScript: p2wsh.output,
|
||||||
|
|
||||||
hasWitness: true,
|
hasWitness: true,
|
||||||
signScript: witnessScript,
|
signScript,
|
||||||
signType: expanded.type,
|
signType: expanded.type,
|
||||||
|
|
||||||
pubkeys: expanded.pubkeys,
|
pubkeys: expanded.pubkeys,
|
||||||
@ -331,12 +337,17 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
|
|||||||
expanded.signatures = input.signatures
|
expanded.signatures = input.signatures
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let signScript = input.prevOutScript
|
||||||
|
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
|
||||||
|
signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prevOutType: expanded.type,
|
prevOutType: expanded.type,
|
||||||
prevOutScript: input.prevOutScript,
|
prevOutScript: input.prevOutScript,
|
||||||
|
|
||||||
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
|
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
|
||||||
signScript: input.prevOutScript,
|
signScript,
|
||||||
signType: expanded.type,
|
signType: expanded.type,
|
||||||
|
|
||||||
pubkeys: expanded.pubkeys,
|
pubkeys: expanded.pubkeys,
|
||||||
|
|||||||
@ -22,7 +22,23 @@ const GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03
|
|||||||
const GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
|
const GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
|
||||||
|
|
||||||
describe('ECPair', function () {
|
describe('ECPair', function () {
|
||||||
describe('constructor', function () {
|
describe('getPublicKey', function () {
|
||||||
|
let keyPair
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
keyPair = ECPair.fromPrivateKey(ONE)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls pointFromScalar lazily', hoodwink(function () {
|
||||||
|
assert.strictEqual(keyPair.__Q, null)
|
||||||
|
|
||||||
|
// .publicKey forces the memoization
|
||||||
|
assert.strictEqual(keyPair.publicKey.toString('hex'), '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
||||||
|
assert.strictEqual(keyPair.__Q.toString('hex'), '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('fromPrivateKey', function () {
|
||||||
it('defaults to compressed', function () {
|
it('defaults to compressed', function () {
|
||||||
const keyPair = ECPair.fromPrivateKey(ONE)
|
const keyPair = ECPair.fromPrivateKey(ONE)
|
||||||
|
|
||||||
@ -49,8 +65,6 @@ describe('ECPair', function () {
|
|||||||
fixtures.valid.forEach(function (f) {
|
fixtures.valid.forEach(function (f) {
|
||||||
it('derives public key for ' + f.WIF, function () {
|
it('derives public key for ' + f.WIF, function () {
|
||||||
const d = Buffer.from(f.d, 'hex')
|
const d = Buffer.from(f.d, 'hex')
|
||||||
console.log(d)
|
|
||||||
|
|
||||||
const keyPair = ECPair.fromPrivateKey(d, {
|
const keyPair = ECPair.fromPrivateKey(d, {
|
||||||
compressed: f.compressed
|
compressed: f.compressed
|
||||||
})
|
})
|
||||||
@ -59,37 +73,25 @@ describe('ECPair', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
fixtures.invalid.constructor.forEach(function (f) {
|
fixtures.invalid.fromPrivateKey.forEach(function (f) {
|
||||||
it('throws ' + f.exception, function () {
|
it('throws ' + f.exception, function () {
|
||||||
if (f.d) {
|
const d = Buffer.from(f.d, 'hex')
|
||||||
const d = Buffer.from(f.d, 'hex')
|
assert.throws(function () {
|
||||||
assert.throws(function () {
|
ECPair.fromPrivateKey(d, f.options)
|
||||||
ECPair.fromPrivateKey(d, f.options)
|
}, new RegExp(f.exception))
|
||||||
}, new RegExp(f.exception))
|
|
||||||
} else {
|
|
||||||
const Q = Buffer.from(f.Q, 'hex')
|
|
||||||
assert.throws(function () {
|
|
||||||
ECPair.fromPublicKey(Q, f.options)
|
|
||||||
}, new RegExp(f.exception))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('getPublicKey', function () {
|
describe('fromPublicKey', function () {
|
||||||
let keyPair
|
fixtures.invalid.fromPublicKey.forEach(function (f) {
|
||||||
|
it('throws ' + f.exception, function () {
|
||||||
beforeEach(function () {
|
const Q = Buffer.from(f.Q, 'hex')
|
||||||
keyPair = ECPair.fromPrivateKey(ONE)
|
assert.throws(function () {
|
||||||
|
ECPair.fromPublicKey(Q, f.options)
|
||||||
|
}, new RegExp(f.exception))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls pointFromScalar lazily', hoodwink(function () {
|
|
||||||
assert.strictEqual(keyPair.__Q, null)
|
|
||||||
|
|
||||||
// .publicKey forces the memoization
|
|
||||||
assert.strictEqual(keyPair.publicKey.toString('hex'), '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
|
||||||
assert.strictEqual(keyPair.__Q.toString('hex'), '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('fromWIF', function () {
|
describe('fromWIF', function () {
|
||||||
|
|||||||
23
test/fixtures/ecpair.json
vendored
23
test/fixtures/ecpair.json
vendored
@ -66,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"invalid": {
|
"invalid": {
|
||||||
"constructor": [
|
"fromPrivateKey": [
|
||||||
{
|
{
|
||||||
"exception": "Private key not in range \\[1, n\\)",
|
"exception": "Private key not in range \\[1, n\\)",
|
||||||
"d": "0000000000000000000000000000000000000000000000000000000000000000"
|
"d": "0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
@ -93,7 +93,26 @@
|
|||||||
"network": {}
|
"network": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"fromPublicKey": [
|
||||||
|
{
|
||||||
|
"exception": "Expected isPoint, got Buffer",
|
||||||
|
"Q": "",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "Expected property \"network.messagePrefix\" of type Buffer|String, got undefined",
|
||||||
|
"Q": "044289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34cec320a0565fb7caf11b1ca2f445f9b7b012dda5718b3cface369ee3a034ded6",
|
||||||
|
"options": {
|
||||||
|
"network": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Bad X coordinate (== P)",
|
||||||
|
"exception": "Expected isPoint, got Buffer",
|
||||||
|
"Q": "040000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
|
||||||
|
"options": {}
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"fromWIF": [
|
"fromWIF": [
|
||||||
{
|
{
|
||||||
|
|||||||
8
test/fixtures/transaction_builder.json
vendored
8
test/fixtures/transaction_builder.json
vendored
@ -394,8 +394,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Transaction w/ P2WPKH -> P2WPKH",
|
"description": "P2WPKH -> P2WPKH",
|
||||||
"txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff011027000000000000160014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c502483045022100b4a9d46ea4d38d6b3ea098911c9f72c0ae6ebc72408e6be7880a6b22a4b3e4da02207996107d0e6437f80363f96f502a38f275156f7501ea51f67899ba78a0c129c101210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000",
|
"txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff011027000000000000160014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c502483045022100a8fc5e4c6d7073474eff2af5d756966e75be0cdfbba299518526080ce8b584be02200f26d41082764df89e3c815b8eaf51034a3b68a25f1be51208f54222c1bb6c1601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
@ -834,7 +834,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "SIGHASH V0+V1, (P2PKH, P2WPKH) -> 2x P2PKH",
|
"description": "SIGHASH V0+V1, (P2PKH, P2WPKH) -> 2x P2PKH",
|
||||||
"txHex": "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000484730440220691a19d365c8d75f921346c70271506bde136f13a4b566dd796902c262e2ec6d02202b00c4aa030eedf294552bdfc163936d2f4e91c59e7798c4471250cf07cb859501eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff0230f45e13000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac00e9a435000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402200a7b08cccedf608e279410091acbd7e990e19a8edf401c3698763d2920de5871022060462ed172a02ecef73ebc19811d8fc72ed68f4419742df70241ad0a5a6a36410121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000",
|
"txHex": "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000484730440220691a19d365c8d75f921346c70271506bde136f13a4b566dd796902c262e2ec6d02202b00c4aa030eedf294552bdfc163936d2f4e91c59e7798c4471250cf07cb859501eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff0230f45e13000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac00e9a435000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac0002483045022100fddd014889f18d489b5400bfa8cb0a32301a768d934b1a0e2b55398119f26cab02207676c64c16ffa7ffaaf8e16b3b74e916687eebdfdb36b9b7997e838384d464640121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
@ -1314,7 +1314,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "P2WPKH -> P2PKH",
|
"description": "P2WPKH -> P2PKH",
|
||||||
"txHex": "0100000000010133defbe3e28860007ff3e21222774c220cb35d554fa3e3796d25bf8ee983e1080000000000ffffffff0160ea0000000000001976a914851a33a5ef0d4279bd5854949174e2c65b1d450088ac02483045022100834f56825e880ab7926164458e10582d9fd8df005396b7e51a1efb8db277204e02206a3610b7101c3242643ac9c9d3487c2d28ffdad19ec26a7f81fc100bdac625f10121038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b00000000",
|
"txHex": "0100000000010133defbe3e28860007ff3e21222774c220cb35d554fa3e3796d25bf8ee983e1080000000000ffffffff0160ea0000000000001976a914851a33a5ef0d4279bd5854949174e2c65b1d450088ac0248304502210097c3006f0b390982eb47f762b2853773c6cedf83668a22d710f4c13c4fd6b15502205e26ef16a81fc818a37f3a34fc6d0700e61100ea6c6773907c9c046042c440340121038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b00000000",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,6 +4,7 @@ const dhttp = require('dhttp/200')
|
|||||||
|
|
||||||
const APIPASS = process.env.APIPASS || 'satoshi'
|
const APIPASS = process.env.APIPASS || 'satoshi'
|
||||||
const APIURL = 'https://api.dcousens.cloud/1'
|
const APIURL = 'https://api.dcousens.cloud/1'
|
||||||
|
const NETWORK = bitcoin.networks.testnet
|
||||||
|
|
||||||
function broadcast (txHex, callback) {
|
function broadcast (txHex, callback) {
|
||||||
dhttp({
|
dhttp({
|
||||||
@ -37,7 +38,35 @@ function faucet (address, value, callback) {
|
|||||||
unspents(address, function (err, results) {
|
unspents(address, function (err, results) {
|
||||||
if (err) return callback(err)
|
if (err) return callback(err)
|
||||||
|
|
||||||
callback(null, results.filter(x => x.txId === txId).pop())
|
const unspents = results.filter(x => x.txId === txId)
|
||||||
|
if (unspents.length === 0) return callback(new Error('Missing unspent'))
|
||||||
|
|
||||||
|
callback(null, unspents.pop())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function faucetComplex (output, value, callback) {
|
||||||
|
const keyPair = bitcoin.ECPair.makeRandom({ network: NETWORK })
|
||||||
|
const p2pkh = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: NETWORK })
|
||||||
|
|
||||||
|
faucet(p2pkh.address, value * 2, (err, unspent) => {
|
||||||
|
if (err) return callback(err)
|
||||||
|
|
||||||
|
const txvb = new bitcoin.TransactionBuilder(NETWORK)
|
||||||
|
txvb.addInput(unspent.txId, unspent.vout, null, p2pkh.output)
|
||||||
|
txvb.addOutput(output, value)
|
||||||
|
txvb.sign(0, keyPair)
|
||||||
|
const txv = txvb.build()
|
||||||
|
|
||||||
|
broadcast(txv.toHex(), function (err) {
|
||||||
|
if (err) return callback(err)
|
||||||
|
|
||||||
|
return callback(null, {
|
||||||
|
txId: txv.getId(),
|
||||||
|
vout: 0,
|
||||||
|
value
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -78,14 +107,15 @@ function randomAddress () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
broadcast: broadcast,
|
broadcast,
|
||||||
faucet: faucet,
|
faucet,
|
||||||
fetch: fetch,
|
faucetComplex,
|
||||||
height: height,
|
fetch,
|
||||||
mine: mine,
|
height,
|
||||||
network: bitcoin.networks.testnet,
|
mine,
|
||||||
unspents: unspents,
|
network: NETWORK,
|
||||||
verify: verify,
|
unspents,
|
||||||
randomAddress: randomAddress,
|
verify,
|
||||||
|
randomAddress,
|
||||||
RANDOM_ADDRESS: randomAddress()
|
RANDOM_ADDRESS: randomAddress()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,9 +7,6 @@ const bip32 = require('bip32')
|
|||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const tinysecp = require('tiny-secp256k1')
|
const tinysecp = require('tiny-secp256k1')
|
||||||
|
|
||||||
const ecurve = require('ecurve')
|
|
||||||
const secp256k1 = ecurve.getCurveByName('secp256k1')
|
|
||||||
|
|
||||||
describe('bitcoinjs-lib (crypto)', function () {
|
describe('bitcoinjs-lib (crypto)', function () {
|
||||||
it('can recover a private key from duplicate R values', function () {
|
it('can recover a private key from duplicate R values', function () {
|
||||||
this.timeout(30000)
|
this.timeout(30000)
|
||||||
@ -29,8 +26,7 @@ describe('bitcoinjs-lib (crypto)', function () {
|
|||||||
input.z = new BN(m)
|
input.z = new BN(m)
|
||||||
})
|
})
|
||||||
|
|
||||||
// finally, run the tasks, then on to the math
|
const n = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16)
|
||||||
const n = new BN(secp256k1.n.toString())
|
|
||||||
|
|
||||||
for (var i = 0; i < tx.ins.length; ++i) {
|
for (var i = 0; i < tx.ins.length; ++i) {
|
||||||
for (var j = i + 1; j < tx.ins.length; ++j) {
|
for (var j = i + 1; j < tx.ins.length; ++j) {
|
||||||
|
|||||||
72
test/integration/payments.js
Normal file
72
test/integration/payments.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* global describe, it */
|
||||||
|
|
||||||
|
const bitcoin = require('../../')
|
||||||
|
|
||||||
|
const regtestUtils = require('./_regtest')
|
||||||
|
const NETWORK = regtestUtils.network
|
||||||
|
const keyPairs = [
|
||||||
|
bitcoin.ECPair.makeRandom({ network: NETWORK }),
|
||||||
|
bitcoin.ECPair.makeRandom({ network: NETWORK })
|
||||||
|
]
|
||||||
|
|
||||||
|
function buildAndSign (depends, prevOutput, redeemScript, witnessScript, done) {
|
||||||
|
regtestUtils.faucetComplex(prevOutput, 5e4, (err, unspent) => {
|
||||||
|
if (err) return done(err)
|
||||||
|
|
||||||
|
const txb = new bitcoin.TransactionBuilder(NETWORK)
|
||||||
|
txb.addInput(unspent.txId, unspent.vout, null, prevOutput)
|
||||||
|
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
|
||||||
|
|
||||||
|
if (depends.signatures) {
|
||||||
|
keyPairs.forEach((keyPair) => {
|
||||||
|
txb.sign(0, keyPair, redeemScript, null, unspent.value, witnessScript)
|
||||||
|
})
|
||||||
|
} else if (depends.signature) {
|
||||||
|
txb.sign(0, keyPairs[0], redeemScript, null, unspent.value, witnessScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
regtestUtils.broadcast(txb.build().toHex(), done)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
;['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach((k) => {
|
||||||
|
const fixtures = require('../fixtures/' + k)
|
||||||
|
const { depends } = fixtures.dynamic
|
||||||
|
const fn = bitcoin.payments[k]
|
||||||
|
|
||||||
|
const base = {}
|
||||||
|
if (depends.pubkey) base.pubkey = keyPairs[0].publicKey
|
||||||
|
if (depends.pubkeys) base.pubkeys = keyPairs.map(x => x.publicKey)
|
||||||
|
if (depends.m) base.m = base.pubkeys.length
|
||||||
|
|
||||||
|
const { output } = fn(base)
|
||||||
|
if (!output) throw new TypeError('Missing output')
|
||||||
|
|
||||||
|
describe('bitcoinjs-lib (payments - ' + k + ')', function () {
|
||||||
|
this.timeout(30000)
|
||||||
|
|
||||||
|
it('can broadcast as an output, and be spent as an input', (done) => {
|
||||||
|
buildAndSign(depends, output, null, null, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can (as P2SH(' + k + ')) broadcast as an output, and be spent as an input', (done) => {
|
||||||
|
const p2sh = bitcoin.payments.p2sh({ redeem: { output }, network: NETWORK })
|
||||||
|
buildAndSign(depends, p2sh.output, p2sh.redeem.output, null, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
// NOTE: P2WPKH cannot be wrapped in P2WSH, consensus fail
|
||||||
|
if (k === 'p2wpkh') return
|
||||||
|
|
||||||
|
it('can (as P2WSH(' + k + ')) broadcast as an output, and be spent as an input', (done) => {
|
||||||
|
const p2wsh = bitcoin.payments.p2wsh({ redeem: { output }, network: NETWORK })
|
||||||
|
buildAndSign(depends, p2wsh.output, null, p2wsh.redeem.output, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can (as P2SH(P2WSH(' + k + '))) broadcast as an output, and be spent as an input', (done) => {
|
||||||
|
const p2wsh = bitcoin.payments.p2wsh({ redeem: { output }, network: NETWORK })
|
||||||
|
const p2sh = bitcoin.payments.p2sh({ redeem: { output: p2wsh.output }, network: NETWORK })
|
||||||
|
|
||||||
|
buildAndSign(depends, p2sh.output, p2sh.redeem.output, p2wsh.redeem.output, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -171,6 +171,67 @@ describe('bitcoinjs-lib (transactions)', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input', function (done) {
|
||||||
|
this.timeout(30000)
|
||||||
|
|
||||||
|
const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
|
||||||
|
const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: regtest })
|
||||||
|
|
||||||
|
regtestUtils.faucetComplex(p2wpkh.address, 5e4, function (err, unspent) {
|
||||||
|
if (err) return done(err)
|
||||||
|
|
||||||
|
// XXX: build the Transaction w/ a P2WPKH input
|
||||||
|
const txb = new bitcoin.TransactionBuilder(regtest)
|
||||||
|
txb.addInput(unspent.txId, unspent.vout, null, p2wpkh.output) // NOTE: provide the prevOutScript!
|
||||||
|
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
|
||||||
|
txb.sign(0, keyPair, null, null, unspent.value) // NOTE: no redeem script
|
||||||
|
const tx = txb.build()
|
||||||
|
|
||||||
|
// build and broadcast (the P2WPKH transaction) to the Bitcoin RegTest network
|
||||||
|
regtestUtils.broadcast(tx.toHex(), function (err) {
|
||||||
|
if (err) return done(err)
|
||||||
|
|
||||||
|
regtestUtils.verify({
|
||||||
|
txId: tx.getId(),
|
||||||
|
address: regtestUtils.RANDOM_ADDRESS,
|
||||||
|
vout: 0,
|
||||||
|
value: 2e4
|
||||||
|
}, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input', function (done) {
|
||||||
|
this.timeout(30000)
|
||||||
|
|
||||||
|
const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
|
||||||
|
const p2pk = bitcoin.payments.p2pk({ pubkey: keyPair.publicKey, network: regtest })
|
||||||
|
const p2wsh = bitcoin.payments.p2wsh({ redeem: p2pk, network: regtest })
|
||||||
|
|
||||||
|
regtestUtils.faucetComplex(p2wsh.address, 5e4, function (err, unspent) {
|
||||||
|
if (err) return done(err)
|
||||||
|
|
||||||
|
// XXX: build the Transaction w/ a P2WSH input
|
||||||
|
const txb = new bitcoin.TransactionBuilder(regtest)
|
||||||
|
txb.addInput(unspent.txId, unspent.vout, null, p2wsh.output) // NOTE: provide the prevOutScript!
|
||||||
|
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
|
||||||
|
txb.sign(0, keyPair, null, null, 5e4, p2wsh.redeem.output) // NOTE: provide a witnessScript!
|
||||||
|
const tx = txb.build()
|
||||||
|
|
||||||
|
// build and broadcast (the P2WSH transaction) to the Bitcoin RegTest network
|
||||||
|
regtestUtils.broadcast(tx.toHex(), function (err) {
|
||||||
|
if (err) return done(err)
|
||||||
|
|
||||||
|
regtestUtils.verify({
|
||||||
|
txId: tx.getId(),
|
||||||
|
address: regtestUtils.RANDOM_ADDRESS,
|
||||||
|
vout: 0,
|
||||||
|
value: 2e4
|
||||||
|
}, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', function (done) {
|
it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', function (done) {
|
||||||
this.timeout(50000)
|
this.timeout(50000)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user