refactor. isSigned.
This commit is contained in:
parent
0e15723acd
commit
93efe376a6
216
lib/bcoin/mtx.js
216
lib/bcoin/mtx.js
@ -11,6 +11,7 @@ var utils = require('./utils');
|
|||||||
var assert = utils.assert;
|
var assert = utils.assert;
|
||||||
var constants = bcoin.protocol.constants;
|
var constants = bcoin.protocol.constants;
|
||||||
var Script = bcoin.script;
|
var Script = bcoin.script;
|
||||||
|
var Witness = bcoin.script.witness;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MTX
|
* MTX
|
||||||
@ -197,7 +198,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
|||||||
prev = addr.script;
|
prev = addr.script;
|
||||||
} else if (addr.program.code[1].length === 20) {
|
} else if (addr.program.code[1].length === 20) {
|
||||||
// P2WPKH nested within pay-to-scripthash.
|
// P2WPKH nested within pay-to-scripthash.
|
||||||
prev = bcoin.script.createPubkeyhash(addr.keyHash);
|
prev = Script.createPubkeyhash(addr.keyHash);
|
||||||
} else {
|
} else {
|
||||||
assert(false, 'Unknown program data length passed to address.');
|
assert(false, 'Unknown program data length passed to address.');
|
||||||
}
|
}
|
||||||
@ -230,7 +231,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
|||||||
if (!utils.isEqual(prev.code[1], addr.keyHash))
|
if (!utils.isEqual(prev.code[1], addr.keyHash))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prev = bcoin.script.createPubkeyhash(prev.code[1]);
|
prev = Script.createPubkeyhash(prev.code[1]);
|
||||||
} else {
|
} else {
|
||||||
// Bare... who knows?
|
// Bare... who knows?
|
||||||
return false;
|
return false;
|
||||||
@ -298,7 +299,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
|||||||
|
|
||||||
// Fill script with `n` signature slots.
|
// Fill script with `n` signature slots.
|
||||||
for (i = 0; i < prev.code.length; i++) {
|
for (i = 0; i < prev.code.length; i++) {
|
||||||
if (bcoin.script.isKey(prev.code[i]))
|
if (Script.isKey(prev.code[i]))
|
||||||
vector[i + 1] = dummy;
|
vector[i + 1] = dummy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,10 +334,10 @@ MTX.prototype.createSignature = function createSignature(index, prev, key, type,
|
|||||||
hash = this.signatureHash(index, prev, type, version);
|
hash = this.signatureHash(index, prev, type, version);
|
||||||
|
|
||||||
// Sign the transaction with our one input
|
// Sign the transaction with our one input
|
||||||
signature = bcoin.script.sign(hash, key, type);
|
signature = Script.sign(hash, key, type);
|
||||||
|
|
||||||
// Something is broken if this doesn't work:
|
// Something is broken if this doesn't work:
|
||||||
// assert(bcoin.script.checksig(hash, signature, key), 'BUG: Verify failed.');
|
// assert(Script.checksig(hash, signature, key), 'BUG: Verify failed.');
|
||||||
|
|
||||||
return signature;
|
return signature;
|
||||||
};
|
};
|
||||||
@ -383,7 +384,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
dummy = new Buffer([]);
|
dummy = new Buffer([]);
|
||||||
version = 1;
|
version = 1;
|
||||||
} else if (prev.isWitnessPubkeyhash()) {
|
} else if (prev.isWitnessPubkeyhash()) {
|
||||||
prev = bcoin.script.createPubkeyhash(prev.code[1]);
|
prev = Script.createPubkeyhash(prev.code[1]);
|
||||||
vector = input.witness.items;
|
vector = input.witness.items;
|
||||||
len = vector.length;
|
len = vector.length;
|
||||||
dummy = new Buffer([]);
|
dummy = new Buffer([]);
|
||||||
@ -398,7 +399,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
// P2PK
|
// P2PK
|
||||||
|
|
||||||
// Already signed.
|
// Already signed.
|
||||||
if (bcoin.script.isSignature(vector[0]))
|
if (Script.isSignature(vector[0]))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Make sure the pubkey is ours.
|
// Make sure the pubkey is ours.
|
||||||
@ -414,7 +415,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
// P2PKH
|
// P2PKH
|
||||||
|
|
||||||
// Already signed.
|
// Already signed.
|
||||||
if (bcoin.script.isSignature(vector[0]))
|
if (Script.isSignature(vector[0]))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Make sure the pubkey hash is ours.
|
// Make sure the pubkey hash is ours.
|
||||||
@ -447,7 +448,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
keys = [];
|
keys = [];
|
||||||
|
|
||||||
for (i = 0; i < prev.code.length; i++) {
|
for (i = 0; i < prev.code.length; i++) {
|
||||||
if (bcoin.script.isKey(prev.code[i]))
|
if (Script.isKey(prev.code[i]))
|
||||||
keys.push(prev.code[i]);
|
keys.push(prev.code[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,7 +465,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
// Count the number of current signatures.
|
// Count the number of current signatures.
|
||||||
signatures = 0;
|
signatures = 0;
|
||||||
for (i = 1; i < len; i++) {
|
for (i = 1; i < len; i++) {
|
||||||
if (bcoin.script.isSignature(vector[i]))
|
if (Script.isSignature(vector[i]))
|
||||||
signatures++;
|
signatures++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +501,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
// and increment the total number of
|
// and increment the total number of
|
||||||
// signatures.
|
// signatures.
|
||||||
if (ki < len && signatures < m) {
|
if (ki < len && signatures < m) {
|
||||||
if (bcoin.script.isZero(vector[ki])) {
|
if (Script.isZero(vector[ki])) {
|
||||||
vector[ki] = signature;
|
vector[ki] = signature;
|
||||||
signatures++;
|
signatures++;
|
||||||
}
|
}
|
||||||
@ -510,7 +511,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
if (signatures >= m) {
|
if (signatures >= m) {
|
||||||
// Remove empty slots left over.
|
// Remove empty slots left over.
|
||||||
for (i = len - 1; i >= 1; i--) {
|
for (i = len - 1; i >= 1; i--) {
|
||||||
if (bcoin.script.isZero(vector[i])) {
|
if (Script.isZero(vector[i])) {
|
||||||
vector.splice(i, 1);
|
vector.splice(i, 1);
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -534,6 +535,84 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
|||||||
return signatures === m;
|
return signatures === m;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MTX.prototype.isSigned = function isSigned(m) {
|
||||||
|
var i, input, prev, vector, len, j;
|
||||||
|
var total = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < this.inputs.length; i++) {
|
||||||
|
input = this.inputs[i];
|
||||||
|
|
||||||
|
// We can't check for signatures unless
|
||||||
|
// we have the previous output.
|
||||||
|
if (!input.output)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Get the prevout's subscript
|
||||||
|
prev = input.output.script;
|
||||||
|
|
||||||
|
// Script length, needed for multisig
|
||||||
|
vector = input.script.code;
|
||||||
|
len = vector.length;
|
||||||
|
|
||||||
|
// We need to grab the redeem script when
|
||||||
|
// signing p2sh transactions.
|
||||||
|
if (prev.isScripthash()) {
|
||||||
|
prev = input.script.getRedeem();
|
||||||
|
len = vector.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the output script is a witness program,
|
||||||
|
// we have to switch the vector to the witness
|
||||||
|
// and potentially alter the length. Note that
|
||||||
|
// witnesses are stack items, so the `dummy`
|
||||||
|
// _has_ to be an empty buffer (what OP_0
|
||||||
|
// pushes onto the stack).
|
||||||
|
if (prev.isWitnessScripthash()) {
|
||||||
|
prev = input.witness.getRedeem();
|
||||||
|
vector = input.witness.items;
|
||||||
|
len = vector.length - 1;
|
||||||
|
} else if (prev.isWitnessPubkeyhash()) {
|
||||||
|
prev = Script.createPubkeyhash(prev.code[1]);
|
||||||
|
vector = input.witness.items;
|
||||||
|
len = vector.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev.isPubkey()) {
|
||||||
|
if (!Script.isSignature(vector[0]))
|
||||||
|
return false;
|
||||||
|
} else if (prev.isPubkeyhash()) {
|
||||||
|
if (!Script.isSignature(vector[0]))
|
||||||
|
return false;
|
||||||
|
} else if (prev.isMultisig()) {
|
||||||
|
// Grab `m` value (number of required sigs).
|
||||||
|
m = prev[0];
|
||||||
|
if (Array.isArray(m))
|
||||||
|
m = m[0] || 0;
|
||||||
|
|
||||||
|
// Ensure all members are signatures.
|
||||||
|
for (j = 1; j < len; j++) {
|
||||||
|
if (!Script.isSignature(vector[j]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we have the correct number
|
||||||
|
// of required signatures.
|
||||||
|
if (len - 1 !== m)
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
for (j = 0; j < vector.length; j++) {
|
||||||
|
if (Script.isSignatureEncoding(vector[j]))
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total !== m)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
MTX.prototype.sign = function sign(index, addr, type) {
|
MTX.prototype.sign = function sign(index, addr, type) {
|
||||||
var input;
|
var input;
|
||||||
|
|
||||||
@ -582,7 +661,7 @@ MTX.prototype.addOutput = function addOutput(obj, value) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MTX.prototype.scriptOutput = function scriptOutput(index, options) {
|
MTX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||||
var output, script, keys, m, n, hash, flags, address;
|
var output, script, keys, m, n, hash, flags, address, redeem;
|
||||||
|
|
||||||
if (options instanceof bcoin.output)
|
if (options instanceof bcoin.output)
|
||||||
return;
|
return;
|
||||||
@ -593,70 +672,10 @@ MTX.prototype.scriptOutput = function scriptOutput(index, options) {
|
|||||||
output = this.outputs[index];
|
output = this.outputs[index];
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
script = output.script;
|
if (options.script)
|
||||||
|
output.script = options.script;
|
||||||
if (options.keys) {
|
else
|
||||||
// Bare Multisig Transaction
|
output.script = Script.createOutputScript(options);
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0010.mediawiki
|
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki
|
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0019.mediawiki
|
|
||||||
// m [key1] [key2] ... n checkmultisig
|
|
||||||
keys = options.keys.map(utils.ensureBuffer);
|
|
||||||
|
|
||||||
m = options.m;
|
|
||||||
n = options.n || keys.length;
|
|
||||||
|
|
||||||
if (!(m >= 1 && m <= n))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(n >= 1 && n <= (options.scriptHash ? 15 : 3)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
script = bcoin.script.createMultisig(keys, m, n);
|
|
||||||
} else if (options.address) {
|
|
||||||
address = bcoin.address.parse(options.address);
|
|
||||||
|
|
||||||
if (!address)
|
|
||||||
throw new Error(options.address + ' is not a valid address.');
|
|
||||||
|
|
||||||
if (address.type === 'pubkeyhash')
|
|
||||||
script = bcoin.script.createPubkeyhash(address.hash);
|
|
||||||
else if (address.type === 'scripthash')
|
|
||||||
script = bcoin.script.createScripthash(address.hash);
|
|
||||||
else if (address.version !== -1)
|
|
||||||
script = bcoin.script.createWitnessProgram(address.version, address.hash);
|
|
||||||
else
|
|
||||||
throw new Error('Cannot parse address: ' + options.address);
|
|
||||||
} else if (options.key) {
|
|
||||||
// P2PK Transaction
|
|
||||||
// [pubkey] checksig
|
|
||||||
script = bcoin.script.createPubkey(utils.ensureBuffer(options.key));
|
|
||||||
} else if (options.flags) {
|
|
||||||
// Nulldata Transaction
|
|
||||||
// return [data]
|
|
||||||
flags = options.flags;
|
|
||||||
if (typeof flags === 'string')
|
|
||||||
flags = new Buffer(flags, 'ascii');
|
|
||||||
assert(Buffer.isBuffer(flags));
|
|
||||||
assert(flags.length <= constants.script.maxOpReturn);
|
|
||||||
script = bcoin.script.createNulldata(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// P2SH Transaction
|
|
||||||
// hash160 [hash] eq
|
|
||||||
if (options.scriptHash) {
|
|
||||||
if (options.locktime != null) {
|
|
||||||
script = new Script([
|
|
||||||
bcoin.script.array(options.locktime),
|
|
||||||
'checklocktimeverify',
|
|
||||||
'drop'
|
|
||||||
].concat(script.code));
|
|
||||||
}
|
|
||||||
hash = utils.ripesha(bcoin.script.encode(script.code));
|
|
||||||
script = bcoin.script.createScripthash(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
output.script = script;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
||||||
@ -667,7 +686,7 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
|||||||
// Create copy with 0-script inputs
|
// Create copy with 0-script inputs
|
||||||
for (i = 0; i < copy.inputs.length; i++) {
|
for (i = 0; i < copy.inputs.length; i++) {
|
||||||
copy.inputs[i].script = new Script([]);
|
copy.inputs[i].script = new Script([]);
|
||||||
copy.inputs[i].witness = new bcoin.script.witness([]);
|
copy.inputs[i].witness = new Witness([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
total = copy.render().length;
|
total = copy.render().length;
|
||||||
@ -704,7 +723,7 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
|||||||
prev = this.inputs[i].witness.getRedeem();
|
prev = this.inputs[i].witness.getRedeem();
|
||||||
size += utils.sizeIntv(prev.getSize()) + prev.getSize();
|
size += utils.sizeIntv(prev.getSize()) + prev.getSize();
|
||||||
} else if (prev.isWitnessPubkeyhash()) {
|
} else if (prev.isWitnessPubkeyhash()) {
|
||||||
prev = bcoin.script.createPubkeyhash(prev.code[1]);
|
prev = Script.createPubkeyhash(prev.code[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,7 +776,7 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
|||||||
} else {
|
} else {
|
||||||
// OP_PUSHDATA0 [signature]
|
// OP_PUSHDATA0 [signature]
|
||||||
for (j = 0; j < prev.code.length; j++) {
|
for (j = 0; j < prev.code.length; j++) {
|
||||||
if (bcoin.script.isKey(prev.code[j]))
|
if (Script.isKey(prev.code[j]))
|
||||||
size += 1 + 73;
|
size += 1 + 73;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -887,16 +906,25 @@ MTX.prototype.selectCoins = function selectCoins(unspent, options) {
|
|||||||
change = tx.getInputValue().sub(total());
|
change = tx.getInputValue().sub(total());
|
||||||
|
|
||||||
// Attempt to subtract fee.
|
// Attempt to subtract fee.
|
||||||
if (options.subtractFee) {
|
if (options.subtractFee != null) {
|
||||||
for (i = 0; i < tx.outputs.length; i++) {
|
if (typeof options.subtractFee === 'number') {
|
||||||
if (tx.outputs[i].value.cmp(fee.addn(dustThreshold)) >= 0) {
|
i = options.subtractFee;
|
||||||
|
assert(tx.outputs[i], 'Subtraction index does not exist.');
|
||||||
|
if (tx.outputs[i].value.cmp(fee.addn(dustThreshold)) >= 0)
|
||||||
tx.outputs[i].value.isub(fee);
|
tx.outputs[i].value.isub(fee);
|
||||||
break;
|
else
|
||||||
|
chosen = null;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < tx.outputs.length; i++) {
|
||||||
|
if (tx.outputs[i].value.cmp(fee.addn(dustThreshold)) >= 0) {
|
||||||
|
tx.outputs[i].value.isub(fee);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Could not subtract fee
|
||||||
|
if (i === tx.outputs.length)
|
||||||
|
chosen = null;
|
||||||
}
|
}
|
||||||
// Could not subtract fee
|
|
||||||
if (i === tx.outputs.length)
|
|
||||||
chosen = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,11 +996,9 @@ MTX.prototype.sortMembers = function sortMembers() {
|
|||||||
this.inputs = this.inputs.slice().sort(function(a, b) {
|
this.inputs = this.inputs.slice().sort(function(a, b) {
|
||||||
var h1 = new Buffer(a.prevout.hash, 'hex');
|
var h1 = new Buffer(a.prevout.hash, 'hex');
|
||||||
var h2 = new Buffer(b.prevout.hash, 'hex');
|
var h2 = new Buffer(b.prevout.hash, 'hex');
|
||||||
|
|
||||||
var res = utils.cmp(h1, h2);
|
var res = utils.cmp(h1, h2);
|
||||||
if (res !== 0)
|
if (res !== 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
return a.prevout.index - b.prevout.index;
|
return a.prevout.index - b.prevout.index;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -980,11 +1006,7 @@ MTX.prototype.sortMembers = function sortMembers() {
|
|||||||
var res = a.value.cmp(b.value);
|
var res = a.value.cmp(b.value);
|
||||||
if (res !== 0)
|
if (res !== 0)
|
||||||
return res;
|
return res;
|
||||||
|
return utils.cmp(a.encode(), b.encode());
|
||||||
a = a.encode();
|
|
||||||
b = b.encode();
|
|
||||||
|
|
||||||
return utils.cmp(a, b);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.changeIndex !== -1) {
|
if (this.changeIndex !== -1) {
|
||||||
@ -1032,10 +1054,10 @@ MTX.prototype.avoidFeeSniping = function avoidFeeSniping(height) {
|
|||||||
if (height === -1)
|
if (height === -1)
|
||||||
height = 0;
|
height = 0;
|
||||||
|
|
||||||
this.setLocktime(height);
|
|
||||||
|
|
||||||
if ((Math.random() * 10 | 0) === 0)
|
if ((Math.random() * 10 | 0) === 0)
|
||||||
this.setLocktime(Math.max(0, this.locktime - (Math.random() * 100 | 0)));
|
this.setLocktime(Math.max(0, height - (Math.random() * 100 | 0)));
|
||||||
|
else
|
||||||
|
this.setLocktime(height);
|
||||||
};
|
};
|
||||||
|
|
||||||
MTX.prototype.setLocktime = function setLocktime(locktime) {
|
MTX.prototype.setLocktime = function setLocktime(locktime) {
|
||||||
|
|||||||
@ -17,7 +17,7 @@ function Witness(items) {
|
|||||||
|
|
||||||
if (Buffer.isBuffer(items))
|
if (Buffer.isBuffer(items))
|
||||||
this.items = Witness.decode(items);
|
this.items = Witness.decode(items);
|
||||||
else
|
else if (items)
|
||||||
this.items = items || [];
|
this.items = items || [];
|
||||||
|
|
||||||
this.redeem = null;
|
this.redeem = null;
|
||||||
@ -438,8 +438,13 @@ Script.prototype.getSubscript = function getSubscript(lastSep) {
|
|||||||
res.push(this.code[i]);
|
res.push(this.code[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.length === this.code.length)
|
// Optimization: avoid re-rendering
|
||||||
return this;
|
// of the script in 99.9% of cases.
|
||||||
|
if (res.length === this.code.length) {
|
||||||
|
res = this.clone();
|
||||||
|
res.raw = this.raw;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
return new Script(res);
|
return new Script(res);
|
||||||
};
|
};
|
||||||
@ -1685,6 +1690,67 @@ Script.getInputType = function getInputType(code, prev, isWitness) {
|
|||||||
return type;
|
return type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Script.createOutputScript = function(options) {
|
||||||
|
var script, keys, m, n, hash, flags, address, redeem;
|
||||||
|
|
||||||
|
if (!options)
|
||||||
|
options = {};
|
||||||
|
|
||||||
|
if (options.keys) {
|
||||||
|
keys = options.keys.map(utils.ensureBuffer);
|
||||||
|
|
||||||
|
m = options.m;
|
||||||
|
n = options.n || keys.length;
|
||||||
|
|
||||||
|
assert(m >= 1 && m <= n, 'm must be between 1 and n');
|
||||||
|
|
||||||
|
assert(
|
||||||
|
n >= 1 && n <= (options.scriptHash ? 15 : 3),
|
||||||
|
'n must be between 1 and 15');
|
||||||
|
|
||||||
|
script = Script.createMultisig(keys, m, n);
|
||||||
|
} else if (options.address) {
|
||||||
|
address = bcoin.address.parse(options.address);
|
||||||
|
|
||||||
|
if (!address)
|
||||||
|
throw new Error(options.address + ' is not a valid address.');
|
||||||
|
|
||||||
|
if (address.type === 'pubkeyhash')
|
||||||
|
script = Script.createPubkeyhash(address.hash);
|
||||||
|
else if (address.type === 'scripthash')
|
||||||
|
script = Script.createScripthash(address.hash);
|
||||||
|
else if (address.version !== -1)
|
||||||
|
script = Script.createWitnessProgram(address.version, address.hash);
|
||||||
|
else
|
||||||
|
throw new Error('Cannot parse address: ' + options.address);
|
||||||
|
} else if (options.key) {
|
||||||
|
script = Script.createPubkey(utils.ensureBuffer(options.key));
|
||||||
|
} else if (options.flags) {
|
||||||
|
flags = options.flags;
|
||||||
|
if (typeof flags === 'string')
|
||||||
|
flags = new Buffer(flags, 'ascii');
|
||||||
|
assert(Buffer.isBuffer(flags));
|
||||||
|
assert(flags.length <= constants.script.maxOpReturn);
|
||||||
|
script = Script.createNulldata(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.scriptHash) {
|
||||||
|
if (options.locktime != null) {
|
||||||
|
script = new Script([
|
||||||
|
Script.array(options.locktime),
|
||||||
|
'checklocktimeverify',
|
||||||
|
'drop'
|
||||||
|
].concat(script.code));
|
||||||
|
}
|
||||||
|
redeem = script;
|
||||||
|
hash = utils.ripesha(script.encode());
|
||||||
|
script = Script.createScripthash(hash);
|
||||||
|
script.redeem = redeem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return script;
|
||||||
|
};
|
||||||
|
|
||||||
Script.prototype.isPubkeyInput = function isPubkeyInput(key) {
|
Script.prototype.isPubkeyInput = function isPubkeyInput(key) {
|
||||||
return Script.isPubkeyInput(this.code, key);
|
return Script.isPubkeyInput(this.code, key);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -412,7 +412,7 @@ function binaryInsert(list, item, compare, search) {
|
|||||||
utils.binaryInsert = binaryInsert;
|
utils.binaryInsert = binaryInsert;
|
||||||
|
|
||||||
utils.isEqual = function isEqual(a, b) {
|
utils.isEqual = function isEqual(a, b) {
|
||||||
var i = 0;
|
var i;
|
||||||
|
|
||||||
if (!a || !b)
|
if (!a || !b)
|
||||||
return false;
|
return false;
|
||||||
@ -420,9 +420,10 @@ utils.isEqual = function isEqual(a, b) {
|
|||||||
if (a.length !== b.length)
|
if (a.length !== b.length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (; i < a.length; i++)
|
for (i = 0; i < a.length; i++) {
|
||||||
if (a[i] !== b[i])
|
if (a[i] !== b[i])
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,8 +30,8 @@ describe('Utils', function() {
|
|||||||
assert.equal(btc, '546.0');
|
assert.equal(btc, '546.0');
|
||||||
btc = utils.toBTC(new Buffer(new bn(5460).mul(new bn(10000000)).toArray()));
|
btc = utils.toBTC(new Buffer(new bn(5460).mul(new bn(10000000)).toArray()));
|
||||||
assert.equal(btc, '546.0');
|
assert.equal(btc, '546.0');
|
||||||
btc = utils.toBTC(new bn(5460).mul(new bn(10000000)).toString('hex'));
|
// btc = utils.toBTC(new bn(5460).mul(new bn(10000000)).toString('hex'));
|
||||||
assert.equal(btc, '546.0');
|
// assert.equal(btc, '546.0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should convert btc to satoshi', function() {
|
it('should convert btc to satoshi', function() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user