Merge branch 'master' into addPsbtMethods

This commit is contained in:
junderw 2020-09-12 00:18:37 +09:00
commit 17c47e9102
No known key found for this signature in database
GPG key ID: B256185D3A971908
22 changed files with 412 additions and 79 deletions

View file

@ -107,12 +107,14 @@ function p2wpkh(a, opts) {
if (hash.length > 0 && !hash.equals(pkh))
throw new TypeError('Hash mismatch');
else hash = pkh;
if (!ecc.isPoint(a.pubkey) || a.pubkey.length !== 33)
throw new TypeError('Invalid pubkey for p2wpkh');
}
if (a.witness) {
if (a.witness.length !== 2) throw new TypeError('Witness is invalid');
if (!bscript.isCanonicalScriptSignature(a.witness[0]))
throw new TypeError('Witness has invalid signature');
if (!ecc.isPoint(a.witness[1]))
if (!ecc.isPoint(a.witness[1]) || a.witness[1].length !== 33)
throw new TypeError('Witness has invalid pubkey');
if (a.signature && !a.signature.equals(a.witness[0]))
throw new TypeError('Signature mismatch');

View file

@ -6,6 +6,7 @@ const bscript = require('../script');
const lazy = require('./lazy');
const typef = require('typeforce');
const OPS = bscript.OPS;
const ecc = require('tiny-secp256k1');
const bech32 = require('bech32');
const EMPTY_BUFFER = Buffer.alloc(0);
function stacksEqual(a, b) {
@ -14,6 +15,18 @@ function stacksEqual(a, b) {
return x.equals(b[i]);
});
}
function chunkHasUncompressedPubkey(chunk) {
if (
Buffer.isBuffer(chunk) &&
chunk.length === 65 &&
chunk[0] === 0x04 &&
ecc.isPoint(chunk)
) {
return true;
} else {
return false;
}
}
// input: <>
// witness: [redeemScriptSig ...] {redeemScript}
// output: OP_0 {sha256(redeemScript)}
@ -166,14 +179,27 @@ function p2wsh(a, opts) {
!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])
)
(a.redeem.input && _rchunks().some(chunkHasUncompressedPubkey)) ||
(a.redeem.output &&
(bscript.decompile(a.redeem.output) || []).some(
chunkHasUncompressedPubkey,
))
) {
throw new TypeError(
'redeem.input or redeem.output contains uncompressed pubkey',
);
}
}
if (a.witness && a.witness.length > 0) {
const wScript = a.witness[a.witness.length - 1];
if (a.redeem && a.redeem.output && !a.redeem.output.equals(wScript))
throw new TypeError('Witness and redeem.output mismatch');
if (
a.witness.some(chunkHasUncompressedPubkey) ||
(bscript.decompile(wScript) || []).some(chunkHasUncompressedPubkey)
)
throw new TypeError('Witness contains uncompressed pubkey');
}
}
return Object.assign(o, a);

View file

@ -125,11 +125,17 @@ class Psbt {
}));
}
get txOutputs() {
return this.__CACHE.__TX.outs.map(output => ({
script: bufferutils_1.cloneBuffer(output.script),
value: output.value,
address: address_1.fromOutputScript(output.script, this.opts.network),
}));
return this.__CACHE.__TX.outs.map(output => {
let address;
try {
address = address_1.fromOutputScript(output.script, this.opts.network);
} catch (_) {}
return {
script: bufferutils_1.cloneBuffer(output.script),
value: output.value,
address,
};
});
}
combine(...those) {
this.data.combine(...those.map(o => o.data));
@ -529,9 +535,9 @@ class Psbt {
keyPair,
sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
) {
return new Promise((resolve, reject) => {
return Promise.resolve().then(() => {
if (!keyPair || !keyPair.publicKey)
return reject(new Error('Need Signer to sign input'));
throw new Error('Need Signer to sign input');
const { hash, sighashType } = getHashAndSighashType(
this.data.inputs,
inputIndex,
@ -539,7 +545,7 @@ class Psbt {
this.__CACHE,
sighashTypes,
);
Promise.resolve(keyPair.sign(hash)).then(signature => {
return Promise.resolve(keyPair.sign(hash)).then(signature => {
const partialSig = [
{
pubkey: keyPair.publicKey,
@ -547,7 +553,6 @@ class Psbt {
},
];
this.data.updateInput(inputIndex, { partialSig });
resolve();
});
});
}