style: add build output after applying prettier
This commit is contained in:
parent
6526000999
commit
0ad8fbc6ba
22 changed files with 217 additions and 203 deletions
|
@ -25,7 +25,7 @@ function fromBech32(address) {
|
|||
return {
|
||||
version: result.words[0],
|
||||
prefix: result.prefix,
|
||||
data: Buffer.from(data)
|
||||
data: Buffer.from(data),
|
||||
};
|
||||
}
|
||||
exports.fromBech32 = fromBech32;
|
||||
|
@ -44,6 +44,7 @@ function toBech32(data, version, prefix) {
|
|||
}
|
||||
exports.toBech32 = toBech32;
|
||||
function fromOutputScript(output, network) {
|
||||
//TODO: Network
|
||||
network = network || networks.bitcoin;
|
||||
try {
|
||||
return payments.p2pkh({ output, network }).address;
|
||||
|
|
21
src/block.js
21
src/block.js
|
@ -10,22 +10,22 @@ const varuint = require('varuint-bitcoin');
|
|||
const errorMerkleNoTxes = new TypeError('Cannot compute merkle root for zero transactions');
|
||||
const errorWitnessNotSegwit = new TypeError('Cannot compute witness commit for non-segwit block');
|
||||
function txesHaveWitnessCommit(transactions) {
|
||||
return transactions instanceof Array &&
|
||||
return (transactions instanceof Array &&
|
||||
transactions[0] &&
|
||||
transactions[0].ins &&
|
||||
transactions[0].ins instanceof Array &&
|
||||
transactions[0].ins[0] &&
|
||||
transactions[0].ins[0].witness &&
|
||||
transactions[0].ins[0].witness instanceof Array &&
|
||||
transactions[0].ins[0].witness.length > 0;
|
||||
transactions[0].ins[0].witness.length > 0);
|
||||
}
|
||||
function anyTxHasWitness(transactions) {
|
||||
return transactions instanceof Array &&
|
||||
return (transactions instanceof Array &&
|
||||
transactions.some(tx => typeof tx === 'object' &&
|
||||
tx.ins instanceof Array &&
|
||||
tx.ins.some(input => typeof input === 'object' &&
|
||||
input.witness instanceof Array &&
|
||||
input.witness.length > 0));
|
||||
input.witness.length > 0)));
|
||||
}
|
||||
class Block {
|
||||
constructor() {
|
||||
|
@ -116,9 +116,7 @@ class Block {
|
|||
// There is no rule for the index of the output, so use filter to find it.
|
||||
// The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed
|
||||
// If multiple commits are found, the output with highest index is assumed.
|
||||
let witnessCommits = this.transactions[0].outs
|
||||
.filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex')))
|
||||
.map(out => out.script.slice(6, 38));
|
||||
let witnessCommits = this.transactions[0].outs.filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex'))).map(out => out.script.slice(6, 38));
|
||||
if (witnessCommits.length === 0)
|
||||
return null;
|
||||
// Use the commit with the highest output (should only be one though)
|
||||
|
@ -141,8 +139,9 @@ class Block {
|
|||
byteLength(headersOnly) {
|
||||
if (headersOnly || !this.transactions)
|
||||
return 80;
|
||||
return 80 + varuint.encodingLength(this.transactions.length) +
|
||||
this.transactions.reduce((a, x) => a + x.byteLength(), 0);
|
||||
return (80 +
|
||||
varuint.encodingLength(this.transactions.length) +
|
||||
this.transactions.reduce((a, x) => a + x.byteLength(), 0));
|
||||
}
|
||||
getHash() {
|
||||
return bcrypto.hash256(this.toBuffer(true));
|
||||
|
@ -197,8 +196,8 @@ class Block {
|
|||
let hasWitnessCommit = this.hasWitnessCommit();
|
||||
if (!hasWitnessCommit && this.hasWitness())
|
||||
return false;
|
||||
return this.__checkMerkleRoot() &&
|
||||
(hasWitnessCommit ? this.__checkWitnessCommit() : true);
|
||||
return (this.__checkMerkleRoot() &&
|
||||
(hasWitnessCommit ? this.__checkWitnessCommit() : true));
|
||||
}
|
||||
checkMerkleRoot() {
|
||||
console.warn('Deprecation Warning: Block method checkMerkleRoot will be ' +
|
||||
|
|
|
@ -18,7 +18,7 @@ const types = {
|
|||
P2SH: 'scripthash',
|
||||
P2WPKH: 'witnesspubkeyhash',
|
||||
P2WSH: 'witnessscripthash',
|
||||
WITNESS_COMMITMENT: 'witnesscommitment'
|
||||
WITNESS_COMMITMENT: 'witnesscommitment',
|
||||
};
|
||||
exports.types = types;
|
||||
function classifyOutput(script) {
|
||||
|
|
|
@ -2,15 +2,21 @@
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const createHash = require('create-hash');
|
||||
function ripemd160(buffer) {
|
||||
return createHash('rmd160').update(buffer).digest();
|
||||
return createHash('rmd160')
|
||||
.update(buffer)
|
||||
.digest();
|
||||
}
|
||||
exports.ripemd160 = ripemd160;
|
||||
function sha1(buffer) {
|
||||
return createHash('sha1').update(buffer).digest();
|
||||
return createHash('sha1')
|
||||
.update(buffer)
|
||||
.digest();
|
||||
}
|
||||
exports.sha1 = sha1;
|
||||
function sha256(buffer) {
|
||||
return createHash('sha256').update(buffer).digest();
|
||||
return createHash('sha256')
|
||||
.update(buffer)
|
||||
.digest();
|
||||
}
|
||||
exports.sha256 = sha256;
|
||||
function hash160(buffer) {
|
||||
|
|
|
@ -8,13 +8,14 @@ const typeforce = require('typeforce');
|
|||
const wif = require('wif');
|
||||
const isOptions = typeforce.maybe(typeforce.compile({
|
||||
compressed: types.maybe(types.Boolean),
|
||||
network: types.maybe(types.Network)
|
||||
network: types.maybe(types.Network),
|
||||
}));
|
||||
class ECPair {
|
||||
constructor(d, Q, options) {
|
||||
if (options === undefined)
|
||||
options = {};
|
||||
this.compressed = options.compressed === undefined ? true : options.compressed;
|
||||
this.compressed =
|
||||
options.compressed === undefined ? true : options.compressed;
|
||||
this.network = options.network || NETWORKS.bitcoin;
|
||||
this.__d = undefined;
|
||||
this.__Q = undefined;
|
||||
|
@ -64,9 +65,11 @@ function fromWIF(string, network) {
|
|||
const version = decoded.version;
|
||||
// list of networks?
|
||||
if (types.Array(network)) {
|
||||
network = network.filter(function (x) {
|
||||
network = network
|
||||
.filter(function (x) {
|
||||
return version === x.wif;
|
||||
}).pop();
|
||||
})
|
||||
.pop();
|
||||
if (!network)
|
||||
throw new Error('Unknown network version');
|
||||
// otherwise, assume a network object (or default to bitcoin)
|
||||
|
@ -78,7 +81,7 @@ function fromWIF(string, network) {
|
|||
}
|
||||
return fromPrivateKey(decoded.privateKey, {
|
||||
compressed: decoded.compressed,
|
||||
network: network
|
||||
network: network,
|
||||
});
|
||||
}
|
||||
exports.fromWIF = fromWIF;
|
||||
|
|
|
@ -5,31 +5,31 @@ exports.bitcoin = {
|
|||
bech32: 'bc',
|
||||
bip32: {
|
||||
public: 0x0488b21e,
|
||||
private: 0x0488ade4
|
||||
private: 0x0488ade4,
|
||||
},
|
||||
pubKeyHash: 0x00,
|
||||
scriptHash: 0x05,
|
||||
wif: 0x80
|
||||
wif: 0x80,
|
||||
};
|
||||
exports.regtest = {
|
||||
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||
bech32: 'bcrt',
|
||||
bip32: {
|
||||
public: 0x043587cf,
|
||||
private: 0x04358394
|
||||
private: 0x04358394,
|
||||
},
|
||||
pubKeyHash: 0x6f,
|
||||
scriptHash: 0xc4,
|
||||
wif: 0xef
|
||||
wif: 0xef,
|
||||
};
|
||||
exports.testnet = {
|
||||
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||
bech32: 'tb',
|
||||
bip32: {
|
||||
public: 0x043587cf,
|
||||
private: 0x04358394
|
||||
private: 0x04358394,
|
||||
},
|
||||
pubKeyHash: 0x6f,
|
||||
scriptHash: 0xc4,
|
||||
wif: 0xef
|
||||
wif: 0xef,
|
||||
};
|
||||
|
|
|
@ -14,14 +14,13 @@ function stacksEqual(a, b) {
|
|||
}
|
||||
// output: OP_RETURN ...
|
||||
function p2data(a, opts) {
|
||||
if (!a.data &&
|
||||
!a.output)
|
||||
if (!a.data && !a.output)
|
||||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
typef({
|
||||
network: typef.maybe(typef.Object),
|
||||
output: typef.maybe(typef.Buffer),
|
||||
data: typef.maybe(typef.arrayOf(typef.Buffer))
|
||||
data: typef.maybe(typef.arrayOf(typef.Buffer)),
|
||||
}, a);
|
||||
const network = a.network || networks_1.bitcoin;
|
||||
const o = { network };
|
||||
|
|
|
@ -14,9 +14,9 @@ function prop(object, name, f) {
|
|||
configurable: true,
|
||||
enumerable: true,
|
||||
value: value,
|
||||
writable: true
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
exports.prop = prop;
|
||||
|
|
|
@ -24,9 +24,8 @@ function p2ms(a, opts) {
|
|||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
function isAcceptableSignature(x) {
|
||||
return bscript.isCanonicalScriptSignature(x) ||
|
||||
(opts.allowIncomplete &&
|
||||
(x === OPS.OP_0)) !== undefined; // eslint-disable-line
|
||||
return (bscript.isCanonicalScriptSignature(x) ||
|
||||
(opts.allowIncomplete && x === OPS.OP_0) !== undefined); // eslint-disable-line
|
||||
}
|
||||
typef({
|
||||
network: typef.maybe(typef.Object),
|
||||
|
@ -35,7 +34,7 @@ function p2ms(a, opts) {
|
|||
output: typef.maybe(typef.Buffer),
|
||||
pubkeys: typef.maybe(typef.arrayOf(ecc.isPoint)),
|
||||
signatures: typef.maybe(typef.arrayOf(isAcceptableSignature)),
|
||||
input: typef.maybe(typef.Buffer)
|
||||
input: typef.maybe(typef.Buffer),
|
||||
}, a);
|
||||
const network = a.network || networks_1.bitcoin;
|
||||
const o = { network };
|
||||
|
@ -131,7 +130,8 @@ function p2ms(a, opts) {
|
|||
if (a.input) {
|
||||
if (a.input[0] !== OPS.OP_0)
|
||||
throw new TypeError('Input is invalid');
|
||||
if (o.signatures.length === 0 || !o.signatures.every(isAcceptableSignature))
|
||||
if (o.signatures.length === 0 ||
|
||||
!o.signatures.every(isAcceptableSignature))
|
||||
throw new TypeError('Input has invalid signature(s)');
|
||||
if (a.signatures && !stacksEqual(a.signatures, o.signatures))
|
||||
throw new TypeError('Signature mismatch');
|
||||
|
|
|
@ -9,11 +9,7 @@ const ecc = require('tiny-secp256k1');
|
|||
// input: {signature}
|
||||
// output: {pubKey} OP_CHECKSIG
|
||||
function p2pk(a, opts) {
|
||||
if (!a.input &&
|
||||
!a.output &&
|
||||
!a.pubkey &&
|
||||
!a.input &&
|
||||
!a.signature)
|
||||
if (!a.input && !a.output && !a.pubkey && !a.input && !a.signature)
|
||||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
typef({
|
||||
|
@ -21,18 +17,17 @@ function p2pk(a, opts) {
|
|||
output: typef.maybe(typef.Buffer),
|
||||
pubkey: typef.maybe(ecc.isPoint),
|
||||
signature: typef.maybe(bscript.isCanonicalScriptSignature),
|
||||
input: typef.maybe(typef.Buffer)
|
||||
input: typef.maybe(typef.Buffer),
|
||||
}, a);
|
||||
const _chunks = lazy.value(function () { return bscript.decompile(a.input); });
|
||||
const _chunks = lazy.value(function () {
|
||||
return bscript.decompile(a.input);
|
||||
});
|
||||
const network = a.network || networks_1.bitcoin;
|
||||
const o = { network };
|
||||
lazy.prop(o, 'output', function () {
|
||||
if (!a.pubkey)
|
||||
return;
|
||||
return bscript.compile([
|
||||
a.pubkey,
|
||||
OPS.OP_CHECKSIG
|
||||
]);
|
||||
return bscript.compile([a.pubkey, OPS.OP_CHECKSIG]);
|
||||
});
|
||||
lazy.prop(o, 'pubkey', function () {
|
||||
if (!a.output)
|
||||
|
|
|
@ -11,11 +11,7 @@ const bs58check = require('bs58check');
|
|||
// input: {signature} {pubkey}
|
||||
// output: OP_DUP OP_HASH160 {hash160(pubkey)} OP_EQUALVERIFY OP_CHECKSIG
|
||||
function p2pkh(a, opts) {
|
||||
if (!a.address &&
|
||||
!a.hash &&
|
||||
!a.output &&
|
||||
!a.pubkey &&
|
||||
!a.input)
|
||||
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.input)
|
||||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
typef({
|
||||
|
@ -25,7 +21,7 @@ function p2pkh(a, opts) {
|
|||
output: typef.maybe(typef.BufferN(25)),
|
||||
pubkey: typef.maybe(ecc.isPoint),
|
||||
signature: typef.maybe(bscript.isCanonicalScriptSignature),
|
||||
input: typef.maybe(typef.Buffer)
|
||||
input: typef.maybe(typef.Buffer),
|
||||
}, a);
|
||||
const _address = lazy.value(function () {
|
||||
const payload = bs58check.decode(a.address);
|
||||
|
@ -33,7 +29,9 @@ function p2pkh(a, opts) {
|
|||
const hash = payload.slice(1);
|
||||
return { version, hash };
|
||||
});
|
||||
const _chunks = lazy.value(function () { return bscript.decompile(a.input); });
|
||||
const _chunks = lazy.value(function () {
|
||||
return bscript.decompile(a.input);
|
||||
});
|
||||
const network = a.network || networks_1.bitcoin;
|
||||
const o = { network };
|
||||
lazy.prop(o, 'address', function () {
|
||||
|
@ -60,7 +58,7 @@ function p2pkh(a, opts) {
|
|||
OPS.OP_HASH160,
|
||||
o.hash,
|
||||
OPS.OP_EQUALVERIFY,
|
||||
OPS.OP_CHECKSIG
|
||||
OPS.OP_CHECKSIG,
|
||||
]);
|
||||
});
|
||||
lazy.prop(o, 'pubkey', function () {
|
||||
|
|
|
@ -18,11 +18,7 @@ function stacksEqual(a, b) {
|
|||
// witness: <?>
|
||||
// output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL
|
||||
function p2sh(a, opts) {
|
||||
if (!a.address &&
|
||||
!a.hash &&
|
||||
!a.output &&
|
||||
!a.redeem &&
|
||||
!a.input)
|
||||
if (!a.address && !a.hash && !a.output && !a.redeem && !a.input)
|
||||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
typef({
|
||||
|
@ -34,10 +30,10 @@ function p2sh(a, opts) {
|
|||
network: typef.maybe(typef.Object),
|
||||
output: typef.maybe(typef.Buffer),
|
||||
input: typef.maybe(typef.Buffer),
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer))
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer)),
|
||||
}),
|
||||
input: typef.maybe(typef.Buffer),
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer))
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer)),
|
||||
}, a);
|
||||
let network = a.network;
|
||||
if (!network) {
|
||||
|
@ -50,14 +46,16 @@ function p2sh(a, opts) {
|
|||
const hash = payload.slice(1);
|
||||
return { version, hash };
|
||||
});
|
||||
const _chunks = lazy.value(function () { return bscript.decompile(a.input); });
|
||||
const _chunks = lazy.value(function () {
|
||||
return bscript.decompile(a.input);
|
||||
});
|
||||
const _redeem = lazy.value(function () {
|
||||
const chunks = _chunks();
|
||||
return {
|
||||
network,
|
||||
output: chunks[chunks.length - 1],
|
||||
input: bscript.compile(chunks.slice(0, -1)),
|
||||
witness: a.witness || []
|
||||
witness: a.witness || [],
|
||||
};
|
||||
});
|
||||
// output dependents
|
||||
|
@ -81,11 +79,7 @@ function p2sh(a, opts) {
|
|||
lazy.prop(o, 'output', function () {
|
||||
if (!o.hash)
|
||||
return;
|
||||
return bscript.compile([
|
||||
OPS.OP_HASH160,
|
||||
o.hash,
|
||||
OPS.OP_EQUAL
|
||||
]);
|
||||
return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]);
|
||||
});
|
||||
// input dependents
|
||||
lazy.prop(o, 'redeem', function () {
|
||||
|
@ -153,7 +147,7 @@ function p2sh(a, opts) {
|
|||
if (hasInput && hasWitness)
|
||||
throw new TypeError('Input and witness provided');
|
||||
if (hasInput) {
|
||||
const richunks = bscript.decompile(redeem.input);
|
||||
const richunks = (bscript.decompile(redeem.input));
|
||||
if (!bscript.isPushOnly(richunks))
|
||||
throw new TypeError('Non push-only scriptSig');
|
||||
}
|
||||
|
|
|
@ -13,11 +13,7 @@ const EMPTY_BUFFER = Buffer.alloc(0);
|
|||
// input: <>
|
||||
// output: OP_0 {pubKeyHash}
|
||||
function p2wpkh(a, opts) {
|
||||
if (!a.address &&
|
||||
!a.hash &&
|
||||
!a.output &&
|
||||
!a.pubkey &&
|
||||
!a.witness)
|
||||
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.witness)
|
||||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
typef({
|
||||
|
@ -28,7 +24,7 @@ function p2wpkh(a, opts) {
|
|||
output: typef.maybe(typef.BufferN(22)),
|
||||
pubkey: typef.maybe(ecc.isPoint),
|
||||
signature: typef.maybe(bscript.isCanonicalScriptSignature),
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer))
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer)),
|
||||
}, a);
|
||||
const _address = lazy.value(function () {
|
||||
const result = bech32.decode(a.address);
|
||||
|
@ -37,7 +33,7 @@ function p2wpkh(a, opts) {
|
|||
return {
|
||||
version,
|
||||
prefix: result.prefix,
|
||||
data: Buffer.from(data)
|
||||
data: Buffer.from(data),
|
||||
};
|
||||
});
|
||||
const network = a.network || networks_1.bitcoin;
|
||||
|
@ -60,10 +56,7 @@ function p2wpkh(a, opts) {
|
|||
lazy.prop(o, 'output', function () {
|
||||
if (!o.hash)
|
||||
return;
|
||||
return bscript.compile([
|
||||
OPS.OP_0,
|
||||
o.hash
|
||||
]);
|
||||
return bscript.compile([OPS.OP_0, o.hash]);
|
||||
});
|
||||
lazy.prop(o, 'pubkey', function () {
|
||||
if (a.pubkey)
|
||||
|
|
|
@ -19,11 +19,7 @@ function stacksEqual(a, b) {
|
|||
// witness: [redeemScriptSig ...] {redeemScript}
|
||||
// output: OP_0 {sha256(redeemScript)}
|
||||
function p2wsh(a, opts) {
|
||||
if (!a.address &&
|
||||
!a.hash &&
|
||||
!a.output &&
|
||||
!a.redeem &&
|
||||
!a.witness)
|
||||
if (!a.address && !a.hash && !a.output && !a.redeem && !a.witness)
|
||||
throw new TypeError('Not enough data');
|
||||
opts = Object.assign({ validate: true }, opts || {});
|
||||
typef({
|
||||
|
@ -35,10 +31,10 @@ function p2wsh(a, opts) {
|
|||
input: typef.maybe(typef.Buffer),
|
||||
network: typef.maybe(typef.Object),
|
||||
output: typef.maybe(typef.Buffer),
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer))
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer)),
|
||||
}),
|
||||
input: typef.maybe(typef.BufferN(0)),
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer))
|
||||
witness: typef.maybe(typef.arrayOf(typef.Buffer)),
|
||||
}, a);
|
||||
const _address = lazy.value(function () {
|
||||
const result = bech32.decode(a.address);
|
||||
|
@ -47,10 +43,12 @@ function p2wsh(a, opts) {
|
|||
return {
|
||||
version,
|
||||
prefix: result.prefix,
|
||||
data: Buffer.from(data)
|
||||
data: Buffer.from(data),
|
||||
};
|
||||
});
|
||||
const _rchunks = lazy.value(function () { return bscript.decompile(a.redeem.input); });
|
||||
const _rchunks = lazy.value(function () {
|
||||
return bscript.decompile(a.redeem.input);
|
||||
});
|
||||
let network = a.network;
|
||||
if (!network) {
|
||||
network = (a.redeem && a.redeem.network) || networks_1.bitcoin;
|
||||
|
@ -74,10 +72,7 @@ function p2wsh(a, opts) {
|
|||
lazy.prop(o, 'output', function () {
|
||||
if (!o.hash)
|
||||
return;
|
||||
return bscript.compile([
|
||||
OPS.OP_0,
|
||||
o.hash
|
||||
]);
|
||||
return bscript.compile([OPS.OP_0, o.hash]);
|
||||
});
|
||||
lazy.prop(o, 'redeem', function () {
|
||||
if (!a.witness)
|
||||
|
@ -85,7 +80,7 @@ function p2wsh(a, opts) {
|
|||
return {
|
||||
output: a.witness[a.witness.length - 1],
|
||||
input: EMPTY_BUFFER,
|
||||
witness: a.witness.slice(0, -1)
|
||||
witness: a.witness.slice(0, -1),
|
||||
};
|
||||
});
|
||||
lazy.prop(o, 'input', function () {
|
||||
|
@ -165,11 +160,15 @@ function p2wsh(a, opts) {
|
|||
}
|
||||
if (a.redeem.input && !bscript.isPushOnly(_rchunks()))
|
||||
throw new TypeError('Non push-only scriptSig');
|
||||
if (a.witness && a.redeem.witness && !stacksEqual(a.witness, a.redeem.witness))
|
||||
if (a.witness &&
|
||||
a.redeem.witness &&
|
||||
!stacksEqual(a.witness, a.redeem.witness))
|
||||
throw new TypeError('Witness and redeem.witness mismatch');
|
||||
}
|
||||
if (a.witness) {
|
||||
if (a.redeem && a.redeem.output && !a.redeem.output.equals(a.witness[a.witness.length - 1]))
|
||||
if (a.redeem &&
|
||||
a.redeem.output &&
|
||||
!a.redeem.output.equals(a.witness[a.witness.length - 1]))
|
||||
throw new TypeError('Witness and redeem.output mismatch');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ exports.OPS = require('bitcoin-ops');
|
|||
const REVERSE_OPS = require('bitcoin-ops/map');
|
||||
const OP_INT_BASE = exports.OPS.OP_RESERVED; // OP_1 - 1
|
||||
function isOPInt(value) {
|
||||
return types.Number(value) &&
|
||||
((value === exports.OPS.OP_0) ||
|
||||
return (types.Number(value) &&
|
||||
(value === exports.OPS.OP_0 ||
|
||||
(value >= exports.OPS.OP_1 && value <= exports.OPS.OP_16) ||
|
||||
(value === exports.OPS.OP_1NEGATE));
|
||||
value === exports.OPS.OP_1NEGATE));
|
||||
}
|
||||
function isPushOnlyChunk(value) {
|
||||
return types.Buffer(value) || isOPInt(value);
|
||||
|
@ -96,7 +96,7 @@ function decompile(buffer) {
|
|||
while (i < buffer.length) {
|
||||
const opcode = buffer[i];
|
||||
// data chunk
|
||||
if ((opcode > exports.OPS.OP_0) && (opcode <= exports.OPS.OP_PUSHDATA4)) {
|
||||
if (opcode > exports.OPS.OP_0 && opcode <= exports.OPS.OP_PUSHDATA4) {
|
||||
const d = pushdata.decode(buffer, i);
|
||||
// did reading a pushDataInt fail?
|
||||
if (d === null)
|
||||
|
@ -129,7 +129,8 @@ function toASM(chunks) {
|
|||
if (chunksIsBuffer(chunks)) {
|
||||
chunks = decompile(chunks);
|
||||
}
|
||||
return chunks.map(function (chunk) {
|
||||
return chunks
|
||||
.map(function (chunk) {
|
||||
// data?
|
||||
if (singleChunkIsBuffer(chunk)) {
|
||||
const op = asMinimalOP(chunk);
|
||||
|
@ -139,7 +140,8 @@ function toASM(chunks) {
|
|||
}
|
||||
// opcode!
|
||||
return REVERSE_OPS[chunk];
|
||||
}).join(' ');
|
||||
})
|
||||
.join(' ');
|
||||
}
|
||||
exports.toASM = toASM;
|
||||
function fromASM(asm) {
|
||||
|
|
|
@ -19,8 +19,8 @@ function decode(buffer, maxLength, minimal) {
|
|||
const a = buffer.readUInt32LE(0);
|
||||
const b = buffer.readUInt8(4);
|
||||
if (b & 0x80)
|
||||
return -(((b & ~0x80) * 0x100000000) + a);
|
||||
return (b * 0x100000000) + a;
|
||||
return -((b & ~0x80) * 0x100000000 + a);
|
||||
return b * 0x100000000 + a;
|
||||
}
|
||||
// 32-bit / 24-bit / 16-bit / 8-bit
|
||||
let result = 0;
|
||||
|
@ -33,11 +33,16 @@ function decode(buffer, maxLength, minimal) {
|
|||
}
|
||||
exports.decode = decode;
|
||||
function scriptNumSize(i) {
|
||||
return i > 0x7fffffff ? 5
|
||||
: i > 0x7fffff ? 4
|
||||
: i > 0x7fff ? 3
|
||||
: i > 0x7f ? 2
|
||||
: i > 0x00 ? 1
|
||||
return i > 0x7fffffff
|
||||
? 5
|
||||
: i > 0x7fffff
|
||||
? 4
|
||||
: i > 0x7fff
|
||||
? 3
|
||||
: i > 0x7f
|
||||
? 2
|
||||
: i > 0x00
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
function encode(number) {
|
||||
|
|
|
@ -34,14 +34,14 @@ function decode(buffer) {
|
|||
const s = fromDER(decode.s);
|
||||
return {
|
||||
signature: Buffer.concat([r, s], 64),
|
||||
hashType: hashType
|
||||
hashType: hashType,
|
||||
};
|
||||
}
|
||||
exports.decode = decode;
|
||||
function encode(signature, hashType) {
|
||||
typeforce({
|
||||
signature: types.BufferN(64),
|
||||
hashType: types.UInt8
|
||||
hashType: types.UInt8,
|
||||
}, { signature, hashType });
|
||||
const hashTypeMod = hashType & ~0x80;
|
||||
if (hashTypeMod <= 0 || hashTypeMod >= 4)
|
||||
|
@ -50,9 +50,6 @@ function encode(signature, hashType) {
|
|||
hashTypeBuffer.writeUInt8(hashType, 0);
|
||||
const r = toDER(signature.slice(0, 32));
|
||||
const s = toDER(signature.slice(32, 64));
|
||||
return Buffer.concat([
|
||||
bip66.encode(r, s),
|
||||
hashTypeBuffer
|
||||
]);
|
||||
return Buffer.concat([bip66.encode(r, s), hashTypeBuffer]);
|
||||
}
|
||||
exports.encode = encode;
|
||||
|
|
|
@ -5,10 +5,11 @@ const bscript = require("../script");
|
|||
const OPS = bscript.OPS;
|
||||
function check(script) {
|
||||
const buffer = bscript.compile(script);
|
||||
return buffer.length > 1 &&
|
||||
buffer[0] === OPS.OP_RETURN;
|
||||
return buffer.length > 1 && buffer[0] === OPS.OP_RETURN;
|
||||
}
|
||||
exports.check = check;
|
||||
check.toJSON = function () { return 'null data output'; };
|
||||
check.toJSON = function () {
|
||||
return 'null data output';
|
||||
};
|
||||
const output = { check };
|
||||
exports.output = output;
|
||||
|
|
|
@ -14,9 +14,10 @@ function varSliceSize(someScript) {
|
|||
}
|
||||
function vectorSize(someVector) {
|
||||
const length = someVector.length;
|
||||
return varuint.encodingLength(length) + someVector.reduce((sum, witness) => {
|
||||
return (varuint.encodingLength(length) +
|
||||
someVector.reduce((sum, witness) => {
|
||||
return sum + varSliceSize(witness);
|
||||
}, 0);
|
||||
}, 0));
|
||||
}
|
||||
const EMPTY_SCRIPT = Buffer.allocUnsafe(0);
|
||||
const EMPTY_WITNESS = [];
|
||||
|
@ -25,7 +26,7 @@ const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000
|
|||
const VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex');
|
||||
const BLANK_OUTPUT = {
|
||||
script: EMPTY_SCRIPT,
|
||||
valueBuffer: VALUE_UINT64_MAX
|
||||
valueBuffer: VALUE_UINT64_MAX,
|
||||
};
|
||||
function isOutput(out) {
|
||||
return out.value !== undefined;
|
||||
|
@ -90,14 +91,14 @@ class Transaction {
|
|||
index: readUInt32(),
|
||||
script: readVarSlice(),
|
||||
sequence: readUInt32(),
|
||||
witness: EMPTY_WITNESS
|
||||
witness: EMPTY_WITNESS,
|
||||
});
|
||||
}
|
||||
const voutLen = readVarInt();
|
||||
for (i = 0; i < voutLen; ++i) {
|
||||
tx.outs.push({
|
||||
value: readUInt64(),
|
||||
script: readVarSlice()
|
||||
script: readVarSlice(),
|
||||
});
|
||||
}
|
||||
if (hasWitnesses) {
|
||||
|
@ -127,7 +128,7 @@ class Transaction {
|
|||
return true;
|
||||
}
|
||||
isCoinbase() {
|
||||
return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash);
|
||||
return (this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash));
|
||||
}
|
||||
addInput(hash, index, sequence, scriptSig) {
|
||||
typeforce(types.tuple(types.Hash256bit, types.UInt32, types.maybe(types.UInt32), types.maybe(types.Buffer)), arguments);
|
||||
|
@ -140,7 +141,7 @@ class Transaction {
|
|||
index: index,
|
||||
script: scriptSig || EMPTY_SCRIPT,
|
||||
sequence: sequence,
|
||||
witness: EMPTY_WITNESS
|
||||
witness: EMPTY_WITNESS,
|
||||
}) - 1);
|
||||
}
|
||||
addOutput(scriptPubKey, value) {
|
||||
|
@ -148,11 +149,11 @@ class Transaction {
|
|||
// Add the output and return the output's index
|
||||
return (this.outs.push({
|
||||
script: scriptPubKey,
|
||||
value: value
|
||||
value: value,
|
||||
}) - 1);
|
||||
}
|
||||
hasWitnesses() {
|
||||
return this.ins.some((x) => {
|
||||
return this.ins.some(x => {
|
||||
return x.witness.length !== 0;
|
||||
});
|
||||
}
|
||||
|
@ -178,27 +179,29 @@ class Transaction {
|
|||
this.outs.reduce((sum, output) => {
|
||||
return sum + 8 + varSliceSize(output.script);
|
||||
}, 0) +
|
||||
(hasWitnesses ? this.ins.reduce((sum, input) => {
|
||||
(hasWitnesses
|
||||
? this.ins.reduce((sum, input) => {
|
||||
return sum + vectorSize(input.witness);
|
||||
}, 0) : 0));
|
||||
}, 0)
|
||||
: 0));
|
||||
}
|
||||
clone() {
|
||||
const newTx = new Transaction();
|
||||
newTx.version = this.version;
|
||||
newTx.locktime = this.locktime;
|
||||
newTx.ins = this.ins.map((txIn) => {
|
||||
newTx.ins = this.ins.map(txIn => {
|
||||
return {
|
||||
hash: txIn.hash,
|
||||
index: txIn.index,
|
||||
script: txIn.script,
|
||||
sequence: txIn.sequence,
|
||||
witness: txIn.witness
|
||||
witness: txIn.witness,
|
||||
};
|
||||
});
|
||||
newTx.outs = this.outs.map((txOut) => {
|
||||
newTx.outs = this.outs.map(txOut => {
|
||||
return {
|
||||
script: txOut.script,
|
||||
value: txOut.value
|
||||
value: txOut.value,
|
||||
};
|
||||
});
|
||||
return newTx;
|
||||
|
@ -217,7 +220,7 @@ class Transaction {
|
|||
if (inIndex >= this.ins.length)
|
||||
return ONE;
|
||||
// ignore OP_CODESEPARATOR
|
||||
const ourScript = bscript.compile(bscript.decompile(prevOutScript).filter((x) => {
|
||||
const ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(x => {
|
||||
return x !== script_1.OPS.OP_CODESEPARATOR;
|
||||
}));
|
||||
const txTmp = this.clone();
|
||||
|
@ -257,7 +260,7 @@ class Transaction {
|
|||
}
|
||||
else {
|
||||
// "blank" others input scripts
|
||||
txTmp.ins.forEach((input) => {
|
||||
txTmp.ins.forEach(input => {
|
||||
input.script = EMPTY_SCRIPT;
|
||||
});
|
||||
txTmp.ins[inIndex].script = ourScript;
|
||||
|
@ -295,7 +298,7 @@ class Transaction {
|
|||
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) {
|
||||
tbuffer = Buffer.allocUnsafe(36 * this.ins.length);
|
||||
toffset = 0;
|
||||
this.ins.forEach((txIn) => {
|
||||
this.ins.forEach(txIn => {
|
||||
writeSlice(txIn.hash);
|
||||
writeUInt32(txIn.index);
|
||||
});
|
||||
|
@ -306,7 +309,7 @@ class Transaction {
|
|||
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
|
||||
tbuffer = Buffer.allocUnsafe(4 * this.ins.length);
|
||||
toffset = 0;
|
||||
this.ins.forEach((txIn) => {
|
||||
this.ins.forEach(txIn => {
|
||||
writeUInt32(txIn.sequence);
|
||||
});
|
||||
hashSequence = bcrypto.hash256(tbuffer);
|
||||
|
@ -318,13 +321,14 @@ class Transaction {
|
|||
}, 0);
|
||||
tbuffer = Buffer.allocUnsafe(txOutsSize);
|
||||
toffset = 0;
|
||||
this.outs.forEach((out) => {
|
||||
this.outs.forEach(out => {
|
||||
writeUInt64(out.value);
|
||||
writeVarSlice(out.script);
|
||||
});
|
||||
hashOutputs = bcrypto.hash256(tbuffer);
|
||||
}
|
||||
else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) {
|
||||
else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE &&
|
||||
inIndex < this.outs.length) {
|
||||
const output = this.outs[inIndex];
|
||||
tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script));
|
||||
toffset = 0;
|
||||
|
@ -369,13 +373,13 @@ class Transaction {
|
|||
offset += slice.copy(buffer, offset);
|
||||
}
|
||||
function writeUInt8(i) {
|
||||
offset = (buffer).writeUInt8(i, offset);
|
||||
offset = buffer.writeUInt8(i, offset);
|
||||
}
|
||||
function writeUInt32(i) {
|
||||
offset = (buffer).writeUInt32LE(i, offset);
|
||||
offset = buffer.writeUInt32LE(i, offset);
|
||||
}
|
||||
function writeInt32(i) {
|
||||
offset = (buffer).writeInt32LE(i, offset);
|
||||
offset = buffer.writeInt32LE(i, offset);
|
||||
}
|
||||
function writeUInt64(i) {
|
||||
offset = bufferutils.writeUInt64LE(buffer, i, offset);
|
||||
|
@ -399,14 +403,14 @@ class Transaction {
|
|||
writeUInt8(Transaction.ADVANCED_TRANSACTION_FLAG);
|
||||
}
|
||||
writeVarInt(this.ins.length);
|
||||
this.ins.forEach((txIn) => {
|
||||
this.ins.forEach(txIn => {
|
||||
writeSlice(txIn.hash);
|
||||
writeUInt32(txIn.index);
|
||||
writeVarSlice(txIn.script);
|
||||
writeUInt32(txIn.sequence);
|
||||
});
|
||||
writeVarInt(this.outs.length);
|
||||
this.outs.forEach((txOut) => {
|
||||
this.outs.forEach(txOut => {
|
||||
if (isOutput(txOut)) {
|
||||
writeUInt64(txOut.value);
|
||||
}
|
||||
|
@ -416,7 +420,7 @@ class Transaction {
|
|||
writeVarSlice(txOut.script);
|
||||
});
|
||||
if (hasWitnesses) {
|
||||
this.ins.forEach((input) => {
|
||||
this.ins.forEach(input => {
|
||||
writeVector(input.witness);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ class TransactionBuilder {
|
|||
txb.__addInputUnsafe(txIn.hash, txIn.index, {
|
||||
sequence: txIn.sequence,
|
||||
script: txIn.script,
|
||||
witness: txIn.witness
|
||||
witness: txIn.witness,
|
||||
});
|
||||
});
|
||||
// fix some things not possible through the public API
|
||||
|
@ -89,7 +89,7 @@ class TransactionBuilder {
|
|||
return this.__addInputUnsafe(txHash, vout, {
|
||||
sequence: sequence,
|
||||
prevOutScript: prevOutScript,
|
||||
value: value
|
||||
value: value,
|
||||
});
|
||||
}
|
||||
__addInputUnsafe(txHash, vout, options) {
|
||||
|
@ -194,7 +194,7 @@ class TransactionBuilder {
|
|||
if (!canSign(input)) {
|
||||
if (witnessValue !== undefined) {
|
||||
if (input.value !== undefined && input.value !== witnessValue)
|
||||
throw new Error('Input didn\'t match witnessValue');
|
||||
throw new Error("Input didn't match witnessValue");
|
||||
typeforce(types.Satoshi, witnessValue);
|
||||
input.value = witnessValue;
|
||||
}
|
||||
|
@ -251,10 +251,11 @@ class TransactionBuilder {
|
|||
}
|
||||
// if inputs are being signed with SIGHASH_NONE, we don't strictly need outputs
|
||||
// .build() will fail, but .buildIncomplete() is OK
|
||||
return (this.__tx.outs.length === 0) && this.__inputs.some((input) => {
|
||||
return (this.__tx.outs.length === 0 &&
|
||||
this.__inputs.some(input => {
|
||||
if (!input.signatures)
|
||||
return false;
|
||||
return input.signatures.some((signature) => {
|
||||
return input.signatures.some(signature => {
|
||||
if (!signature)
|
||||
return false; // no signature, no issue
|
||||
const hashType = signatureHashType(signature);
|
||||
|
@ -262,7 +263,7 @@ class TransactionBuilder {
|
|||
return false; // SIGHASH_NONE doesn't care about outputs
|
||||
return true; // SIGHASH_* does care
|
||||
});
|
||||
});
|
||||
}));
|
||||
}
|
||||
__canModifyOutputs() {
|
||||
const nInputs = this.__tx.ins.length;
|
||||
|
@ -313,21 +314,25 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) {
|
|||
}
|
||||
switch (type) {
|
||||
case SCRIPT_TYPES.P2WPKH: {
|
||||
const { output, pubkey, signature } = payments.p2wpkh({ witness: witnessStack });
|
||||
const { output, pubkey, signature } = payments.p2wpkh({
|
||||
witness: witnessStack,
|
||||
});
|
||||
return {
|
||||
prevOutScript: output,
|
||||
prevOutType: SCRIPT_TYPES.P2WPKH,
|
||||
pubkeys: [pubkey],
|
||||
signatures: [signature]
|
||||
signatures: [signature],
|
||||
};
|
||||
}
|
||||
case SCRIPT_TYPES.P2PKH: {
|
||||
const { output, pubkey, signature } = payments.p2pkh({ input: scriptSig });
|
||||
const { output, pubkey, signature } = payments.p2pkh({
|
||||
input: scriptSig,
|
||||
});
|
||||
return {
|
||||
prevOutScript: output,
|
||||
prevOutType: SCRIPT_TYPES.P2PKH,
|
||||
pubkeys: [pubkey],
|
||||
signatures: [signature]
|
||||
signatures: [signature],
|
||||
};
|
||||
}
|
||||
case SCRIPT_TYPES.P2PK: {
|
||||
|
@ -335,26 +340,26 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) {
|
|||
return {
|
||||
prevOutType: SCRIPT_TYPES.P2PK,
|
||||
pubkeys: [undefined],
|
||||
signatures: [signature]
|
||||
signatures: [signature],
|
||||
};
|
||||
}
|
||||
case SCRIPT_TYPES.P2MS: {
|
||||
const { m, pubkeys, signatures } = payments.p2ms({
|
||||
input: scriptSig,
|
||||
output: scriptPubKey
|
||||
output: scriptPubKey,
|
||||
}, { allowIncomplete: true });
|
||||
return {
|
||||
prevOutType: SCRIPT_TYPES.P2MS,
|
||||
pubkeys: pubkeys,
|
||||
signatures: signatures,
|
||||
maxSignatures: m
|
||||
maxSignatures: m,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (type === SCRIPT_TYPES.P2SH) {
|
||||
const { output, redeem } = payments.p2sh({
|
||||
input: scriptSig,
|
||||
witness: witnessStack
|
||||
witness: witnessStack,
|
||||
});
|
||||
const outputType = classify.output(redeem.output);
|
||||
const expanded = expandInput(redeem.input, redeem.witness, outputType, redeem.output);
|
||||
|
@ -368,13 +373,13 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) {
|
|||
witnessScript: expanded.witnessScript,
|
||||
witnessScriptType: expanded.witnessScriptType,
|
||||
pubkeys: expanded.pubkeys,
|
||||
signatures: expanded.signatures
|
||||
signatures: expanded.signatures,
|
||||
};
|
||||
}
|
||||
if (type === SCRIPT_TYPES.P2WSH) {
|
||||
const { output, redeem } = payments.p2wsh({
|
||||
input: scriptSig,
|
||||
witness: witnessStack
|
||||
witness: witnessStack,
|
||||
});
|
||||
const outputType = classify.output(redeem.output);
|
||||
let expanded;
|
||||
|
@ -392,12 +397,12 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) {
|
|||
witnessScript: redeem.output,
|
||||
witnessScriptType: expanded.prevOutType,
|
||||
pubkeys: expanded.pubkeys,
|
||||
signatures: expanded.signatures
|
||||
signatures: expanded.signatures,
|
||||
};
|
||||
}
|
||||
return {
|
||||
prevOutType: SCRIPT_TYPES.NONSTANDARD,
|
||||
prevOutScript: scriptSig
|
||||
prevOutScript: scriptSig,
|
||||
};
|
||||
}
|
||||
// could be done in expandInput, but requires the original Transaction for hashForSignature
|
||||
|
@ -444,7 +449,7 @@ function expandOutput(script, ourPubKey) {
|
|||
return {
|
||||
type,
|
||||
pubkeys: [ourPubKey],
|
||||
signatures: [undefined]
|
||||
signatures: [undefined],
|
||||
};
|
||||
}
|
||||
case SCRIPT_TYPES.P2WPKH: {
|
||||
|
@ -458,7 +463,7 @@ function expandOutput(script, ourPubKey) {
|
|||
return {
|
||||
type,
|
||||
pubkeys: [ourPubKey],
|
||||
signatures: [undefined]
|
||||
signatures: [undefined],
|
||||
};
|
||||
}
|
||||
case SCRIPT_TYPES.P2PK: {
|
||||
|
@ -466,7 +471,7 @@ function expandOutput(script, ourPubKey) {
|
|||
return {
|
||||
type,
|
||||
pubkeys: [p2pk.pubkey],
|
||||
signatures: [undefined]
|
||||
signatures: [undefined],
|
||||
};
|
||||
}
|
||||
case SCRIPT_TYPES.P2MS: {
|
||||
|
@ -475,7 +480,7 @@ function expandOutput(script, ourPubKey) {
|
|||
type,
|
||||
pubkeys: p2ms.pubkeys,
|
||||
signatures: p2ms.pubkeys.map(() => undefined),
|
||||
maxSignatures: p2ms.m
|
||||
maxSignatures: p2ms.m,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -483,7 +488,7 @@ function expandOutput(script, ourPubKey) {
|
|||
}
|
||||
function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
||||
if (redeemScript && witnessScript) {
|
||||
const p2wsh = payments.p2wsh({ redeem: { output: witnessScript } });
|
||||
const p2wsh = (payments.p2wsh({ redeem: { output: witnessScript } }));
|
||||
const p2wshAlt = payments.p2wsh({ output: redeemScript });
|
||||
const p2sh = payments.p2sh({ redeem: { output: redeemScript } });
|
||||
const p2shAlt = payments.p2sh({ redeem: p2wsh });
|
||||
|
@ -494,7 +499,10 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
throw new Error('Redeem script inconsistent with prevOutScript');
|
||||
const expanded = expandOutput(p2wsh.redeem.output, ourPubKey);
|
||||
if (!expanded.pubkeys)
|
||||
throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')');
|
||||
throw new Error(expanded.type +
|
||||
' not supported as witnessScript (' +
|
||||
bscript.toASM(witnessScript) +
|
||||
')');
|
||||
if (input.signatures && input.signatures.some(x => x !== undefined)) {
|
||||
expanded.signatures = input.signatures;
|
||||
}
|
||||
|
@ -513,7 +521,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
signType: expanded.type,
|
||||
pubkeys: expanded.pubkeys,
|
||||
signatures: expanded.signatures,
|
||||
maxSignatures: expanded.maxSignatures
|
||||
maxSignatures: expanded.maxSignatures,
|
||||
};
|
||||
}
|
||||
if (redeemScript) {
|
||||
|
@ -531,7 +539,10 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
}
|
||||
const expanded = expandOutput(p2sh.redeem.output, ourPubKey);
|
||||
if (!expanded.pubkeys)
|
||||
throw new Error(expanded.type + ' not supported as redeemScript (' + bscript.toASM(redeemScript) + ')');
|
||||
throw new Error(expanded.type +
|
||||
' not supported as redeemScript (' +
|
||||
bscript.toASM(redeemScript) +
|
||||
')');
|
||||
if (input.signatures && input.signatures.some(x => x !== undefined)) {
|
||||
expanded.signatures = input.signatures;
|
||||
}
|
||||
|
@ -549,7 +560,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
signType: expanded.type,
|
||||
pubkeys: expanded.pubkeys,
|
||||
signatures: expanded.signatures,
|
||||
maxSignatures: expanded.maxSignatures
|
||||
maxSignatures: expanded.maxSignatures,
|
||||
};
|
||||
}
|
||||
if (witnessScript) {
|
||||
|
@ -561,7 +572,10 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
}
|
||||
const expanded = expandOutput(p2wsh.redeem.output, ourPubKey);
|
||||
if (!expanded.pubkeys)
|
||||
throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')');
|
||||
throw new Error(expanded.type +
|
||||
' not supported as witnessScript (' +
|
||||
bscript.toASM(witnessScript) +
|
||||
')');
|
||||
if (input.signatures && input.signatures.some(x => x !== undefined)) {
|
||||
expanded.signatures = input.signatures;
|
||||
}
|
||||
|
@ -578,7 +592,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
signType: expanded.type,
|
||||
pubkeys: expanded.pubkeys,
|
||||
signatures: expanded.signatures,
|
||||
maxSignatures: expanded.maxSignatures
|
||||
maxSignatures: expanded.maxSignatures,
|
||||
};
|
||||
}
|
||||
if (input.prevOutType && input.prevOutScript) {
|
||||
|
@ -591,13 +605,16 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
throw new Error('PrevOutScript is missing');
|
||||
const expanded = expandOutput(input.prevOutScript, ourPubKey);
|
||||
if (!expanded.pubkeys)
|
||||
throw new Error(expanded.type + ' not supported (' + bscript.toASM(input.prevOutScript) + ')');
|
||||
throw new Error(expanded.type +
|
||||
' not supported (' +
|
||||
bscript.toASM(input.prevOutScript) +
|
||||
')');
|
||||
if (input.signatures && input.signatures.some(x => x !== undefined)) {
|
||||
expanded.signatures = input.signatures;
|
||||
}
|
||||
let signScript = input.prevOutScript;
|
||||
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
|
||||
signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output;
|
||||
signScript = (payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output);
|
||||
}
|
||||
return {
|
||||
prevOutType: expanded.type,
|
||||
|
@ -607,7 +624,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
signType: expanded.type,
|
||||
pubkeys: expanded.pubkeys,
|
||||
signatures: expanded.signatures,
|
||||
maxSignatures: expanded.maxSignatures
|
||||
maxSignatures: expanded.maxSignatures,
|
||||
};
|
||||
}
|
||||
const prevOutScript = payments.p2pkh({ pubkey: ourPubKey }).output;
|
||||
|
@ -618,7 +635,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) {
|
|||
signScript: prevOutScript,
|
||||
signType: SCRIPT_TYPES.P2PKH,
|
||||
pubkeys: [ourPubKey],
|
||||
signatures: [undefined]
|
||||
signatures: [undefined],
|
||||
};
|
||||
}
|
||||
function build(type, input, allowIncomplete) {
|
||||
|
@ -656,7 +673,7 @@ function build(type, input, allowIncomplete) {
|
|||
}
|
||||
// if the transaction is not not complete (complete), or if signatures.length === m, validate
|
||||
// otherwise, the number of OP_0's may be >= m, so don't validate (boo)
|
||||
const validate = !allowIncomplete || (m === signatures.length);
|
||||
const validate = !allowIncomplete || m === signatures.length;
|
||||
return payments.p2ms({ m, pubkeys, signatures }, { allowIncomplete, validate });
|
||||
}
|
||||
case SCRIPT_TYPES.P2SH: {
|
||||
|
@ -667,8 +684,8 @@ function build(type, input, allowIncomplete) {
|
|||
redeem: {
|
||||
output: redeem.output || input.redeemScript,
|
||||
input: redeem.input,
|
||||
witness: redeem.witness
|
||||
}
|
||||
witness: redeem.witness,
|
||||
},
|
||||
});
|
||||
}
|
||||
case SCRIPT_TYPES.P2WSH: {
|
||||
|
@ -679,21 +696,20 @@ function build(type, input, allowIncomplete) {
|
|||
redeem: {
|
||||
output: input.witnessScript,
|
||||
input: redeem.input,
|
||||
witness: redeem.witness
|
||||
}
|
||||
witness: redeem.witness,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function canSign(input) {
|
||||
return input.signScript !== undefined &&
|
||||
return (input.signScript !== undefined &&
|
||||
input.signType !== undefined &&
|
||||
input.pubkeys !== undefined &&
|
||||
input.signatures !== undefined &&
|
||||
input.signatures.length === input.pubkeys.length &&
|
||||
input.pubkeys.length > 0 &&
|
||||
(input.hasWitness === false ||
|
||||
input.value !== undefined);
|
||||
(input.hasWitness === false || input.value !== undefined));
|
||||
}
|
||||
function signatureHashType(buffer) {
|
||||
return buffer.readUInt8(buffer.length - 1);
|
||||
|
|
|
@ -10,7 +10,9 @@ function BIP32Path(value) {
|
|||
return typeforce.String(value) && !!value.match(/^(m\/)?(\d+'?\/)*\d+'?$/);
|
||||
}
|
||||
exports.BIP32Path = BIP32Path;
|
||||
BIP32Path.toJSON = function () { return 'BIP32 derivation path'; };
|
||||
BIP32Path.toJSON = function () {
|
||||
return 'BIP32 derivation path';
|
||||
};
|
||||
const SATOSHI_MAX = 21 * 1e14;
|
||||
function Satoshi(value) {
|
||||
return typeforce.UInt53(value) && value <= SATOSHI_MAX;
|
||||
|
@ -23,11 +25,11 @@ exports.Network = typeforce.compile({
|
|||
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
|
||||
bip32: {
|
||||
public: typeforce.UInt32,
|
||||
private: typeforce.UInt32
|
||||
private: typeforce.UInt32,
|
||||
},
|
||||
pubKeyHash: typeforce.UInt8,
|
||||
scriptHash: typeforce.UInt8,
|
||||
wif: typeforce.UInt8
|
||||
wif: typeforce.UInt8,
|
||||
});
|
||||
exports.Buffer256bit = typeforce.BufferN(32);
|
||||
exports.Hash160bit = typeforce.BufferN(20);
|
||||
|
|
2
types/index.d.ts
vendored
2
types/index.d.ts
vendored
|
@ -5,7 +5,7 @@ import * as crypto from './crypto';
|
|||
import * as networks from './networks';
|
||||
import * as payments from './payments';
|
||||
import * as script from './script';
|
||||
export { ECPair, address, bip32, crypto, networks, payments, script, };
|
||||
export { ECPair, address, bip32, crypto, networks, payments, script };
|
||||
export { Block } from './block';
|
||||
export { Transaction } from './transaction';
|
||||
export { TransactionBuilder } from './transaction_builder';
|
||||
|
|
Loading…
Reference in a new issue