Compare commits

...

32 Commits

Author SHA1 Message Date
Daniel Cousens
fbaad04f24
Merge pull request #1165 from fybwid/patch-1
Update README.md
2018-08-08 13:30:17 +10:00
Yosef Benny Widyokarsono
64b9646870
Update README.md
Fix example anchor at Documentation
2018-08-08 10:53:20 +08:00
Jonathan Underwood
e672875394
Merge pull request #1160 from bitcoinjs/notealt
CHANGELOG: note alternative to templates
2018-08-07 10:54:10 +09:00
Daniel Cousens
e639914d22
CHANGELOG: note alternative to templates 2018-08-03 10:34:49 +10:00
Jonathan Underwood
836f2b4263
Merge pull request #1146 from bitcoinjs/ectests
tests/ECPair: test fromPublic/fromPrivate in isolation
2018-08-01 11:47:05 +09:00
Daniel Cousens
85b1b92b6d tests/ECPair: test fromPublic/fromPrivate in isolation 2018-07-26 18:05:39 +10:00
Jonathan Underwood
d8b66641b3
Merge pull request #1139 from bitcoinjs/deps
4.0.1 | bump dependencies to 1.0.0 versions (and simplify Travis)
2018-07-23 17:30:00 +09:00
Daniel Cousens
3bb3b9f397 4.0.1 2018-07-23 17:07:42 +10:00
Daniel Cousens
29fc067696 CHANGELOG: add 4.0.1 2018-07-23 17:07:42 +10:00
Daniel Cousens
94f0ae85e3 tests/integration: fix ecurve import, as removed 2018-07-23 16:54:33 +10:00
Daniel Cousens
ffa5ad7c28 bump .travis to use the LTS notation 2018-07-23 16:24:15 +10:00
Daniel Cousens
d9e8a13cde bump dependencies to 1.0.0 versions 2018-07-23 15:53:08 +10:00
Jonathan Underwood
d67e9758c7
Merge pull request #1135 from bitcoinjs/moretests
Add additional payments integration tests
2018-07-23 13:31:28 +09:00
Daniel Cousens
079d83d887 txbuilder: note consensus issue 2018-07-23 10:41:01 +10:00
Daniel Cousens
ca4c9ca64c add note about P2WPKH in P2WSH as a consensus fail 2018-07-23 10:37:31 +10:00
Daniel Cousens
31ab9bfc03 tests/integration: throw verbose error if unspent is missing 2018-07-20 17:35:34 +10:00
Daniel Cousens
de0259a820 tests/integration/payments: enable failing P2SH(P2WSH(P2WPKH)) tests 2018-07-20 17:30:29 +10:00
Daniel Cousens
faf3645361 tests/integration: allow more time 2018-07-20 17:13:25 +10:00
Daniel Cousens
b2d3a2cf30 testing: add payments tests for each standard payment type 2018-07-20 16:50:55 +10:00
Daniel Cousens
732df83346 tests/integration: simplify the bare witness examples 2018-07-20 16:50:55 +10:00
Daniel Cousens
b7e7d879b3
Merge pull request #1134 from ChoiKyubum/master
fix example links of README.md
2018-07-18 12:46:15 +10:00
Kyubum Choi
9368124513 fix links of README.md 2018-07-18 11:26:34 +09:00
junderw
71b2eff813
Merge branch '400' 2018-07-17 22:14:56 +09:00
Jonathan Underwood
4b7c49d92d
Merge pull request #1133 from bitcoinjs/p2wpkhtest
tests: add bare P2W* integration tests (and fix a bug)
2018-07-17 21:58:01 +09:00
Daniel Cousens
74756ed597 TransactionBuilder: fix P2WPKH not using a P2PKH signScript for P2WPKH 2018-07-17 22:33:32 +10:00
Daniel Cousens
5e91c83e0a tests/fixtures: amend TxBuilder P2WPKH fixtures 2018-07-17 22:33:32 +10:00
Daniel Cousens
51792c3528 tests/integration: add bare witness output tests 2018-07-17 22:33:32 +10:00
Daniel Cousens
c34ccdbeb9
Merge pull request #1132 from bitcoinjs/lts
Remove Node 6, update to Node LTS
2018-07-17 22:32:18 +10:00
Daniel Cousens
0bdf6beda1 package: bump to Node 8 and above 2018-07-17 16:54:29 +10:00
Daniel Cousens
7484b84589 travis: rm Node 6 2018-07-17 16:54:07 +10:00
Daniel Cousens
7727a62ae6 4.0.0 2018-07-17 16:48:28 +10:00
Daniel Cousens
a8a9b63d33 CHANGELOG: add missing getNetwork removal 2018-07-17 16:48:28 +10:00
13 changed files with 302 additions and 107 deletions

View File

@ -1,16 +1,14 @@
sudo: false
language: node_js
node_js:
- "6"
- "7"
- "8"
- "lts/*"
- "9"
- "10"
matrix:
include:
- node_js: "6"
- node_js: "lts/*"
env: TEST_SUITE=standard
- node_js: "6"
- node_js: "lts/*"
env: TEST_SUITE=coverage
env:
- TEST_SUITE=unit

View File

@ -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
__added__
- 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.getPrivateKey`, use `ECPair.prototype.privateKey` 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 `HDNode`, use `bip32` export instead (#1073)
- Removed `bufferutils` (#1035)
- Removed `networks.litecoin`, BYO non-Bitcoin networks instead (#1095)
- 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 public access to `ECPair` constructor, use exported functions `ECPair.fromPrivateKey`, `ECPair.fromWIF`, `ECPair.makeRandom`, or `ECPair.fromPublicKey` (#1070)

View File

@ -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.
## 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
@ -82,42 +82,45 @@ The below examples are implemented as integration tests, they should be very eas
Otherwise, pull requests are appreciated.
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 an address from a SHA256 hash](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L37)
- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L48)
- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L55)
- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L69)
- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L78)
- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L88)
- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L103)
- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L117)
- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L136)
- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L146)
- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L21)
- [Create a 2-to-2 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L36)
- [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 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 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 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 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L184)
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L17)
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L24)
- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L35)
- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L44)
- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L59)
- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L75)
- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L92)
- [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 (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 (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)
- [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)
- [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#L29)
- [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#L47)
- [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#L67)
- [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#L90)
- [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#L123)
- [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#L13)
- [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#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#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#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#L143)
- [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)
- [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)
- [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)
- [Verify a Transaction signature](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L304)
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L12)
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L20)
- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L31)
- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L40)
- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L55)
- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L71)
- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L86)
- [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 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)
- [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 (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L94)
- [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)
- [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 (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L150)
- [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#L72)
- [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#L107)
- [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#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)!

View File

@ -1,10 +1,10 @@
{
"name": "bitcoinjs-lib",
"version": "3.3.2",
"version": "4.0.1",
"description": "Client-side Bitcoin JavaScript library",
"main": "./src/index.js",
"engines": {
"node": ">=4.0.0"
"node": ">=8.0.0"
},
"keywords": [
"bitcoinjs",
@ -31,7 +31,7 @@
],
"dependencies": {
"bech32": "^1.1.2",
"bip32": "^0.1.0",
"bip32": "^1.0.0",
"bip66": "^1.1.0",
"bitcoin-ops": "^1.4.0",
"bs58check": "^2.0.0",
@ -41,7 +41,7 @@
"pushdata-bitcoin": "^1.0.1",
"randombytes": "^2.0.1",
"safe-buffer": "^5.1.1",
"tiny-secp256k1": "^0.2.2",
"tiny-secp256k1": "^1.0.0",
"typeforce": "^1.11.3",
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"

View File

@ -5,9 +5,6 @@ const types = require('./types')
const wif = require('wif')
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({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
@ -57,7 +54,7 @@ function fromPrivateKey (buffer, options) {
}
function fromPublicKey (buffer, options) {
typeforce(isPoint, buffer)
typeforce(ecc.isPoint, buffer)
typeforce(isOptions, options)
return new ECPair(null, buffer, options)
}

View File

@ -232,18 +232,21 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
expanded.signatures = input.signatures
}
let signScript = witnessScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2SH(P2WSH(P2WPKH)) is a consensus failure')
return {
redeemScript: redeemScript,
redeemScript,
redeemScriptType: SCRIPT_TYPES.P2WSH,
witnessScript: witnessScript,
witnessScript,
witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output,
hasWitness: true,
signScript: witnessScript,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
@ -274,14 +277,14 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
}
return {
redeemScript: redeemScript,
redeemScript,
redeemScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output,
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
signScript: signScript,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
@ -303,15 +306,18 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
expanded.signatures = input.signatures
}
let signScript = witnessScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2WSH(P2WPKH) is a consensus failure')
return {
witnessScript: witnessScript,
witnessScript,
witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2WSH,
prevOutScript: p2wsh.output,
hasWitness: true,
signScript: witnessScript,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
@ -331,12 +337,17 @@ function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScri
expanded.signatures = input.signatures
}
let signScript = input.prevOutScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output
}
return {
prevOutType: expanded.type,
prevOutScript: input.prevOutScript,
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
signScript: input.prevOutScript,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,

View File

@ -22,7 +22,23 @@ const GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03
const GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
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 () {
const keyPair = ECPair.fromPrivateKey(ONE)
@ -49,8 +65,6 @@ describe('ECPair', function () {
fixtures.valid.forEach(function (f) {
it('derives public key for ' + f.WIF, function () {
const d = Buffer.from(f.d, 'hex')
console.log(d)
const keyPair = ECPair.fromPrivateKey(d, {
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 () {
if (f.d) {
const d = Buffer.from(f.d, 'hex')
assert.throws(function () {
ECPair.fromPrivateKey(d, f.options)
}, new RegExp(f.exception))
} else {
const Q = Buffer.from(f.Q, 'hex')
assert.throws(function () {
ECPair.fromPublicKey(Q, f.options)
}, new RegExp(f.exception))
}
const d = Buffer.from(f.d, 'hex')
assert.throws(function () {
ECPair.fromPrivateKey(d, f.options)
}, new RegExp(f.exception))
})
})
})
describe('getPublicKey', function () {
let keyPair
beforeEach(function () {
keyPair = ECPair.fromPrivateKey(ONE)
describe('fromPublicKey', function () {
fixtures.invalid.fromPublicKey.forEach(function (f) {
it('throws ' + f.exception, function () {
const Q = Buffer.from(f.Q, 'hex')
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 () {

View File

@ -66,7 +66,7 @@
}
],
"invalid": {
"constructor": [
"fromPrivateKey": [
{
"exception": "Private key not in range \\[1, n\\)",
"d": "0000000000000000000000000000000000000000000000000000000000000000"
@ -93,7 +93,26 @@
"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": [
{

View File

@ -394,8 +394,8 @@
]
},
{
"description": "Transaction w/ P2WPKH -> P2WPKH",
"txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff011027000000000000160014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c502483045022100b4a9d46ea4d38d6b3ea098911c9f72c0ae6ebc72408e6be7880a6b22a4b3e4da02207996107d0e6437f80363f96f502a38f275156f7501ea51f67899ba78a0c129c101210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000",
"description": "P2WPKH -> P2WPKH",
"txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff011027000000000000160014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c502483045022100a8fc5e4c6d7073474eff2af5d756966e75be0cdfbba299518526080ce8b584be02200f26d41082764df89e3c815b8eaf51034a3b68a25f1be51208f54222c1bb6c1601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800000000",
"version": 1,
"inputs": [
{
@ -834,7 +834,7 @@
},
{
"description": "SIGHASH V0+V1, (P2PKH, P2WPKH) -> 2x P2PKH",
"txHex": "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000484730440220691a19d365c8d75f921346c70271506bde136f13a4b566dd796902c262e2ec6d02202b00c4aa030eedf294552bdfc163936d2f4e91c59e7798c4471250cf07cb859501eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff0230f45e13000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac00e9a435000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402200a7b08cccedf608e279410091acbd7e990e19a8edf401c3698763d2920de5871022060462ed172a02ecef73ebc19811d8fc72ed68f4419742df70241ad0a5a6a36410121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000",
"txHex": "01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000484730440220691a19d365c8d75f921346c70271506bde136f13a4b566dd796902c262e2ec6d02202b00c4aa030eedf294552bdfc163936d2f4e91c59e7798c4471250cf07cb859501eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff0230f45e13000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac00e9a435000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac0002483045022100fddd014889f18d489b5400bfa8cb0a32301a768d934b1a0e2b55398119f26cab02207676c64c16ffa7ffaaf8e16b3b74e916687eebdfdb36b9b7997e838384d464640121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000",
"version": 1,
"inputs": [
{
@ -1314,7 +1314,7 @@
},
{
"description": "P2WPKH -> P2PKH",
"txHex": "0100000000010133defbe3e28860007ff3e21222774c220cb35d554fa3e3796d25bf8ee983e1080000000000ffffffff0160ea0000000000001976a914851a33a5ef0d4279bd5854949174e2c65b1d450088ac02483045022100834f56825e880ab7926164458e10582d9fd8df005396b7e51a1efb8db277204e02206a3610b7101c3242643ac9c9d3487c2d28ffdad19ec26a7f81fc100bdac625f10121038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b00000000",
"txHex": "0100000000010133defbe3e28860007ff3e21222774c220cb35d554fa3e3796d25bf8ee983e1080000000000ffffffff0160ea0000000000001976a914851a33a5ef0d4279bd5854949174e2c65b1d450088ac0248304502210097c3006f0b390982eb47f762b2853773c6cedf83668a22d710f4c13c4fd6b15502205e26ef16a81fc818a37f3a34fc6d0700e61100ea6c6773907c9c046042c440340121038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b00000000",
"version": 1,
"inputs": [
{

View File

@ -4,6 +4,7 @@ const dhttp = require('dhttp/200')
const APIPASS = process.env.APIPASS || 'satoshi'
const APIURL = 'https://api.dcousens.cloud/1'
const NETWORK = bitcoin.networks.testnet
function broadcast (txHex, callback) {
dhttp({
@ -37,7 +38,35 @@ function faucet (address, value, callback) {
unspents(address, function (err, results) {
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 = {
broadcast: broadcast,
faucet: faucet,
fetch: fetch,
height: height,
mine: mine,
network: bitcoin.networks.testnet,
unspents: unspents,
verify: verify,
randomAddress: randomAddress,
broadcast,
faucet,
faucetComplex,
fetch,
height,
mine,
network: NETWORK,
unspents,
verify,
randomAddress,
RANDOM_ADDRESS: randomAddress()
}

View File

@ -7,9 +7,6 @@ const bip32 = require('bip32')
const crypto = require('crypto')
const tinysecp = require('tiny-secp256k1')
const ecurve = require('ecurve')
const secp256k1 = ecurve.getCurveByName('secp256k1')
describe('bitcoinjs-lib (crypto)', function () {
it('can recover a private key from duplicate R values', function () {
this.timeout(30000)
@ -29,8 +26,7 @@ describe('bitcoinjs-lib (crypto)', function () {
input.z = new BN(m)
})
// finally, run the tasks, then on to the math
const n = new BN(secp256k1.n.toString())
const n = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 16)
for (var i = 0; i < tx.ins.length; ++i) {
for (var j = i + 1; j < tx.ins.length; ++j) {

View 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)
})
})
})

View File

@ -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) {
this.timeout(50000)