new scripting system.
This commit is contained in:
parent
bf8475afe1
commit
b528965912
@ -77,7 +77,7 @@ bcoin.ec = require('./bcoin/ec');
|
||||
bcoin.lru = require('./bcoin/lru');
|
||||
bcoin.protocol = require('./bcoin/protocol');
|
||||
bcoin.bloom = require('./bcoin/bloom');
|
||||
bcoin.script = require('./bcoin/script');
|
||||
bcoin.script = require('./bcoin/script2');
|
||||
bcoin.input = require('./bcoin/input');
|
||||
bcoin.output = require('./bcoin/output');
|
||||
bcoin.coin = require('./bcoin/coin');
|
||||
|
||||
@ -111,13 +111,12 @@ Address.prototype.getScript = function getScript() {
|
||||
assert(this.keys.length === this.n, 'Not all keys have been added.');
|
||||
|
||||
redeem = bcoin.script.createMultisig(this.keys, this.m, this.n);
|
||||
redeem = bcoin.script.encode(redeem);
|
||||
|
||||
if (this.witness) {
|
||||
if (redeem.length > 10000)
|
||||
if (redeem.getSize() > 10000)
|
||||
throw new Error('Redeem script too large (10000 byte limit).');
|
||||
} else {
|
||||
if (redeem.length > 520)
|
||||
if (redeem.getSize() > 520)
|
||||
throw new Error('Redeem script too large (520 byte limit).');
|
||||
}
|
||||
|
||||
@ -140,12 +139,12 @@ Address.prototype.getProgram = function getProgram() {
|
||||
0, Address.hash160(this.getPublicKey()));
|
||||
} else if (this.type === 'multisig') {
|
||||
program = bcoin.script.createWitnessProgram(
|
||||
0, Address.sha256(this.getScript()));
|
||||
0, Address.sha256(this.getScript().encode()));
|
||||
}
|
||||
|
||||
assert(program);
|
||||
|
||||
this._program = bcoin.script.encode(program);
|
||||
this._program = program;
|
||||
|
||||
return this._program;
|
||||
};
|
||||
@ -157,7 +156,7 @@ Address.prototype.getProgramHash = function getProgramHash() {
|
||||
if (this._programHash)
|
||||
return this._programHash;
|
||||
|
||||
this._programHash = Address.hash160(this.getProgram());
|
||||
this._programHash = Address.hash160(this.getProgram().encode());
|
||||
|
||||
return this._programHash;
|
||||
};
|
||||
@ -186,7 +185,7 @@ Address.prototype.getScriptHash160 = function getScriptHash256() {
|
||||
if (this._scriptHash160)
|
||||
return this._scriptHash160;
|
||||
|
||||
this._scriptHash160 = Address.hash160(this.getScript());
|
||||
this._scriptHash160 = Address.hash160(this.getScript().encode());
|
||||
|
||||
return this._scriptHash160;
|
||||
};
|
||||
@ -198,7 +197,7 @@ Address.prototype.getScriptHash256 = function getScriptHash256() {
|
||||
if (this._scriptHash256)
|
||||
return this._scriptHash256;
|
||||
|
||||
this._scriptHash256 = Address.sha256(this.getScript());
|
||||
this._scriptHash256 = Address.sha256(this.getScript().encode());
|
||||
|
||||
return this._scriptHash256;
|
||||
};
|
||||
|
||||
@ -215,7 +215,7 @@ Block.prototype._verify = function _verify() {
|
||||
};
|
||||
|
||||
Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
|
||||
var coinbase, s, height;
|
||||
var coinbase, code, height;
|
||||
|
||||
if (this.version < 2)
|
||||
return -1;
|
||||
@ -228,10 +228,10 @@ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
|
||||
if (!coinbase || coinbase.inputs.length === 0)
|
||||
return -1;
|
||||
|
||||
s = coinbase.inputs[0].script;
|
||||
code = coinbase.inputs[0].script.code;
|
||||
|
||||
if (Buffer.isBuffer(s[0]) && s[0].length <= 6)
|
||||
height = new bn(s[0], 'le').toNumber();
|
||||
if (Buffer.isBuffer(code[0]) && code[0].length <= 6)
|
||||
height = new bn(code[0], 'le').toNumber();
|
||||
else
|
||||
height = -1;
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ function Coin(tx, index) {
|
||||
assert(typeof this.version === 'number');
|
||||
assert(utils.isFinite(this.height));
|
||||
assert(this.value instanceof bn);
|
||||
assert(Array.isArray(this.script));
|
||||
assert(this.script instanceof bcoin.script);
|
||||
assert(typeof this.hash === 'string');
|
||||
assert(utils.isFinite(this.index));
|
||||
assert(typeof this.spent === 'boolean');
|
||||
@ -73,7 +73,7 @@ Coin.prototype.__defineGetter__('chain', function() {
|
||||
});
|
||||
|
||||
Coin.prototype.getSize = function getSize() {
|
||||
return 4 + 4 + 8 + bcoin.script.getSize(this.script) + 32 + 4 + 1;
|
||||
return 4 + 4 + 8 + this.script.getSize() + 32 + 4 + 1;
|
||||
};
|
||||
|
||||
Coin.prototype.getConfirmations = function getConfirmations(height) {
|
||||
@ -136,7 +136,7 @@ Coin.prototype.toJSON = function toJSON() {
|
||||
version: this.version,
|
||||
height: this.height,
|
||||
value: utils.btc(this.value),
|
||||
script: utils.toHex(bcoin.script.encode(this.script)),
|
||||
script: utils.toHex(this.script.encode()),
|
||||
hash: utils.revHex(this.hash),
|
||||
index: this.index,
|
||||
spent: this.spent
|
||||
@ -148,7 +148,7 @@ Coin._fromJSON = function _fromJSON(json) {
|
||||
version: json.version,
|
||||
height: json.height,
|
||||
value: utils.satoshi(json.value),
|
||||
script: bcoin.script.decode(new Buffer(json.script, 'hex')),
|
||||
script: new bcoin.script(new Buffer(json.script, 'hex')),
|
||||
hash: utils.revHex(json.hash),
|
||||
index: json.index,
|
||||
spent: json.spent
|
||||
|
||||
@ -9,6 +9,7 @@ var bcoin = require('../bcoin');
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.protocol.constants;
|
||||
var Script = bcoin.script;
|
||||
|
||||
/**
|
||||
* Input
|
||||
@ -21,7 +22,7 @@ function Input(options, tx) {
|
||||
assert(typeof options.script !== 'string');
|
||||
|
||||
this.prevout = options.prevout;
|
||||
this.script = options.script || [];
|
||||
this.script = options.script || new Script([]);
|
||||
this.sequence = options.sequence == null ? 0xffffffff : options.sequence;
|
||||
this.witness = options.witness || [];
|
||||
this._size = options._size || 0;
|
||||
@ -61,7 +62,7 @@ Input.prototype.getType = function getType() {
|
||||
type = bcoin.script.getInputType(this.witness, null, true);
|
||||
|
||||
if (!type || type === 'unknown')
|
||||
type = bcoin.script.getInputType(this.script);
|
||||
type = this.script.getInputType();
|
||||
|
||||
if (!this._mutable)
|
||||
this._type = type;
|
||||
@ -81,8 +82,10 @@ Input.prototype.getRedeem = function getRedeem() {
|
||||
return bcoin.script.getRedeem(this.witness);
|
||||
|
||||
if (type === 'scripthash') {
|
||||
redeem = bcoin.script.getRedeem(this.script);
|
||||
if (bcoin.script.isWitnessScripthash(redeem))
|
||||
redeem = this.script.getRedeem();
|
||||
if (!redeem)
|
||||
return;
|
||||
if (redeem.isWitnessScripthash())
|
||||
return bcoin.script.getRedeem(this.witness);
|
||||
return redeem;
|
||||
}
|
||||
@ -99,7 +102,7 @@ Input.prototype.getSubtype = function getSubtype() {
|
||||
if (!redeem)
|
||||
return;
|
||||
|
||||
return bcoin.script.getOutputType(redeem);
|
||||
return redeem.getType();
|
||||
};
|
||||
|
||||
Input.prototype.getAddress = function getAddress() {
|
||||
@ -118,7 +121,7 @@ Input.prototype.getAddress = function getAddress() {
|
||||
address = bcoin.script.getInputAddress(this.witness, null, true);
|
||||
|
||||
if (!address)
|
||||
address = bcoin.script.getInputAddress(this.script);
|
||||
address = this.script.getInputAddress();
|
||||
|
||||
if (!this._mutable)
|
||||
this._address = address;
|
||||
@ -142,13 +145,13 @@ Input.prototype.getLocktime = function getLocktime() {
|
||||
output = this.output;
|
||||
redeem = output.script;
|
||||
|
||||
if (bcoin.script.isScripthash(redeem))
|
||||
redeem = bcoin.script.getRedeem(this.script);
|
||||
if (redeem.isScripthash())
|
||||
redeem = this.script.getRedeem();
|
||||
|
||||
if (redeem[1] !== 'checklocktimeverify')
|
||||
return;
|
||||
|
||||
return bcoin.script.getLocktime(redeem);
|
||||
return redeem.getLocktime();
|
||||
};
|
||||
|
||||
Input.prototype.isCoinbase = function isCoinbase() {
|
||||
@ -177,51 +180,12 @@ Input.prototype.test = function test(addressTable) {
|
||||
return false;
|
||||
};
|
||||
|
||||
Input.prototype.getSigops = function getSigops(scriptHash, accurate) {
|
||||
var n = bcoin.script.getSigops(this.script, accurate);
|
||||
if (scriptHash && !this.isCoinbase())
|
||||
n += bcoin.script.getScripthashSigops(this.script);
|
||||
return n;
|
||||
};
|
||||
|
||||
Input.prototype.getID = function getID() {
|
||||
var data = bcoin.script.encode(this.script);
|
||||
var data = this.script.encode();
|
||||
var hash = utils.toHex(utils.ripesha(data));
|
||||
return '[' + this.type + ':' + hash.slice(0, 7) + ']';
|
||||
};
|
||||
|
||||
Input.prototype.getData = function getData() {
|
||||
var def, data;
|
||||
|
||||
assert(this instanceof Input);
|
||||
|
||||
def = {
|
||||
side: 'input',
|
||||
value: new bn(0),
|
||||
script: this.script,
|
||||
sequence: this.sequence
|
||||
};
|
||||
|
||||
def.prev = this.prevout.hash;
|
||||
def.index = this.prevout.index;
|
||||
|
||||
if (this.isCoinbase()) {
|
||||
data = bcoin.script.getCoinbaseData(this.script);
|
||||
return utils.merge(def, data, {
|
||||
type: 'coinbase',
|
||||
none: true
|
||||
});
|
||||
}
|
||||
|
||||
if (this.output) {
|
||||
data = bcoin.script.getInputData(this.script, this.output.script);
|
||||
data.value = this.output.value;
|
||||
return utils.merge(def, data);
|
||||
}
|
||||
|
||||
return utils.merge(def, bcoin.script.getInputData(this.script));
|
||||
};
|
||||
|
||||
Input.prototype.inspect = function inspect() {
|
||||
var redeem = this.getRedeem();
|
||||
var output;
|
||||
@ -262,7 +226,7 @@ Input.prototype.toJSON = function toJSON() {
|
||||
index: this.prevout.index
|
||||
},
|
||||
output: this.output ? this.output.toJSON() : null,
|
||||
script: utils.toHex(bcoin.script.encode(this.script)),
|
||||
script: utils.toHex(this.script.encode()),
|
||||
witness: utils.toHex(bcoin.protocol.framer.witness(this.witness)),
|
||||
sequence: this.sequence
|
||||
};
|
||||
@ -275,7 +239,7 @@ Input._fromJSON = function _fromJSON(json) {
|
||||
index: json.prevout.index
|
||||
},
|
||||
output: json.output ? bcoin.coin._fromJSON(json.output) : null,
|
||||
script: bcoin.script.decode(new Buffer(json.script, 'hex')),
|
||||
script: new Script(new Buffer(json.script, 'hex')),
|
||||
witness: bcoin.protocol.parser.parseWitness(new Buffer(json.witness, 'hex')),
|
||||
sequence: json.sequence
|
||||
};
|
||||
|
||||
160
lib/bcoin/mtx.js
160
lib/bcoin/mtx.js
@ -10,6 +10,7 @@ var bcoin = require('../bcoin');
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.protocol.constants;
|
||||
var Script = bcoin.script;
|
||||
|
||||
/**
|
||||
* MTX
|
||||
@ -140,7 +141,7 @@ MTX.prototype.addInput = function addInput(options, index) {
|
||||
input = bcoin.input(options, this);
|
||||
|
||||
if (options.script)
|
||||
input.script = options.script.slice();
|
||||
input.script = options.script.clone();
|
||||
|
||||
if (options.witness)
|
||||
input.witness = options.witness.slice();
|
||||
@ -166,7 +167,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
// Optimization: Don't bother with any below
|
||||
// calculation if the output is already templated.
|
||||
// Just say this is "our" output.
|
||||
if (input.script.length || input.witness.length)
|
||||
if (input.script.code.length || input.witness.length)
|
||||
return true;
|
||||
|
||||
// Optimization: test output against the
|
||||
@ -182,67 +183,67 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
// This is easily the hardest part about building a transaction
|
||||
// with segwit: figuring out where the redeem script and witness
|
||||
// redeem scripts go.
|
||||
if (bcoin.script.isScripthash(prev)) {
|
||||
if (addr.program && utils.isEqual(prev[1], addr.programHash)) {
|
||||
if (prev.isScripthash()) {
|
||||
if (addr.program && utils.isEqual(prev.code[1], addr.programHash)) {
|
||||
// Witness program nested in regular P2SH.
|
||||
redeemScript = addr.program;
|
||||
redeemScript = addr.program.encode();
|
||||
vector = input.witness;
|
||||
dummy = new Buffer([]);
|
||||
assert(addr.program[0] === 0, 'Non-zero version passed to address.');
|
||||
if (addr.program.length === 34) {
|
||||
assert(addr.program.code[0] === 0, 'Non-zero version passed to address.');
|
||||
if (addr.program.code[1].length === 32) {
|
||||
// P2WSH nested within pay-to-scripthash
|
||||
// (it had to be this complicated, didn't it?)
|
||||
witnessScript = addr.script;
|
||||
prev = bcoin.script.decode(addr.script);
|
||||
} else if (addr.program.length === 22) {
|
||||
witnessScript = addr.script.encode();
|
||||
prev = addr.script;
|
||||
} else if (addr.program.code[1].length === 20) {
|
||||
// P2WPKH nested within pay-to-scripthash.
|
||||
prev = bcoin.script.createPubkeyhash(addr.keyHash);
|
||||
} else {
|
||||
assert(false, 'Unknown program data length passed to address.');
|
||||
}
|
||||
} else if (addr.script && utils.isEqual(prev[1], addr.scriptHash160)) {
|
||||
} else if (addr.script && utils.isEqual(prev.code[1], addr.scriptHash160)) {
|
||||
// Regular P2SH.
|
||||
redeemScript = addr.script;
|
||||
prev = bcoin.script.decode(addr.script);
|
||||
vector = input.script;
|
||||
redeemScript = addr.script.encode();
|
||||
vector = input.script.code;
|
||||
prev = addr.script;
|
||||
dummy = 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (bcoin.script.isWitnessProgram(prev)) {
|
||||
} else if (prev.isWitnessProgram()) {
|
||||
// Witness program.
|
||||
vector = input.witness;
|
||||
dummy = new Buffer([]);
|
||||
|
||||
if (prev[0] !== 0)
|
||||
if (prev.code[0] !== 0)
|
||||
return false;
|
||||
|
||||
if (prev[1].length === 32) {
|
||||
if (prev.code[1].length === 32) {
|
||||
// Bare P2WSH.
|
||||
if (!addr.script || !utils.isEqual(prev[1], addr.scriptHash256))
|
||||
if (!addr.script || !utils.isEqual(prev.code[1], addr.scriptHash256))
|
||||
return false;
|
||||
|
||||
witnessScript = addr.script;
|
||||
prev = bcoin.script.decode(addr.script);
|
||||
} else if (prev[1].length === 20) {
|
||||
witnessScript = addr.script.encode();
|
||||
prev = addr.script;
|
||||
} else if (prev.code[1].length === 20) {
|
||||
// Bare P2WPKH.
|
||||
if (!utils.isEqual(prev[1], addr.keyHash))
|
||||
if (!utils.isEqual(prev.code[1], addr.keyHash))
|
||||
return false;
|
||||
|
||||
prev = bcoin.script.createPubkeyhash(prev[1]);
|
||||
prev = bcoin.script.createPubkeyhash(prev.code[1]);
|
||||
} else {
|
||||
// Bare... who knows?
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Wow, a normal output! Praise be to Jengus and Gord.
|
||||
vector = input.script;
|
||||
vector = input.script.code;
|
||||
dummy = 0;
|
||||
}
|
||||
|
||||
if (bcoin.script.isPubkey(prev)) {
|
||||
if (prev.isPubkey()) {
|
||||
// P2PK
|
||||
if (!utils.isEqual(prev[0], addr.publicKey))
|
||||
if (!utils.isEqual(prev.code[0], addr.publicKey))
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
@ -250,9 +251,9 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
return true;
|
||||
|
||||
vector[0] = dummy;
|
||||
} else if (bcoin.script.isPubkeyhash(prev)) {
|
||||
} else if (prev.isPubkeyhash()) {
|
||||
// P2PKH
|
||||
if (!utils.isEqual(prev[2], addr.keyHash))
|
||||
if (!utils.isEqual(prev.code[2], addr.keyHash))
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
@ -261,9 +262,9 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
|
||||
vector[0] = dummy;
|
||||
vector[1] = addr.publicKey;
|
||||
} else if (bcoin.script.isMultisig(prev)) {
|
||||
} else if (prev.isMultisig()) {
|
||||
// Multisig
|
||||
if (utils.indexOf(prev, addr.publicKey) === -1)
|
||||
if (utils.indexOf(prev.code, addr.publicKey) === -1)
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
@ -276,13 +277,13 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
vector[0] = dummy;
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = prev[prev.length - 2];
|
||||
n = prev.code[prev.code.length - 2];
|
||||
|
||||
// Fill script with `n` signature slots.
|
||||
for (i = 0; i < n; i++)
|
||||
vector[i + 1] = dummy;
|
||||
} else {
|
||||
if (utils.indexOf(prev, addr.publicKey) === -1)
|
||||
if (utils.indexOf(prev.code, addr.publicKey) === -1)
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
@ -296,8 +297,8 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
vector[0] = dummy;
|
||||
|
||||
// Fill script with `n` signature slots.
|
||||
for (i = 0; i < prev.length; i++) {
|
||||
if (bcoin.script.isKey(prev[i]))
|
||||
for (i = 0; i < prev.code.length; i++) {
|
||||
if (bcoin.script.isKey(prev.code[i]))
|
||||
vector[i + 1] = dummy;
|
||||
}
|
||||
}
|
||||
@ -305,7 +306,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
// P2SH requires the redeem
|
||||
// script after signatures.
|
||||
if (redeemScript)
|
||||
input.script.push(redeemScript);
|
||||
input.script.code.push(redeemScript);
|
||||
|
||||
// P2WSH requires the witness
|
||||
// script after signatures.
|
||||
@ -316,7 +317,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
};
|
||||
|
||||
MTX.prototype.createSignature = function createSignature(index, prev, key, type, version) {
|
||||
var prev, hash, signature;
|
||||
var hash, signature;
|
||||
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
@ -357,15 +358,15 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
// Get the previous output's subscript
|
||||
prev = input.output.script;
|
||||
|
||||
vector = input.script;
|
||||
vector = input.script.code;
|
||||
len = vector.length;
|
||||
dummy = 0;
|
||||
version = 0;
|
||||
|
||||
// We need to grab the redeem script when
|
||||
// signing p2sh transactions.
|
||||
if (bcoin.script.isScripthash(prev)) {
|
||||
prev = bcoin.script.getRedeem(input.script);
|
||||
if (prev.isScripthash()) {
|
||||
prev = input.script.getRedeem();
|
||||
len = vector.length - 1;
|
||||
}
|
||||
|
||||
@ -375,14 +376,14 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
// witnesses are stack items, so the `dummy`
|
||||
// _has_ to be an empty buffer (what OP_0
|
||||
// pushes onto the stack).
|
||||
if (bcoin.script.isWitnessScripthash(prev)) {
|
||||
if (prev.isWitnessScripthash()) {
|
||||
prev = bcoin.script.getRedeem(input.witness);
|
||||
vector = input.witness;
|
||||
len = vector.length - 1;
|
||||
dummy = new Buffer([]);
|
||||
version = 1;
|
||||
} else if (bcoin.script.isWitnessPubkeyhash(prev)) {
|
||||
prev = bcoin.script.createPubkeyhash(prev[1]);
|
||||
} else if (prev.isWitnessPubkeyhash()) {
|
||||
prev = bcoin.script.createPubkeyhash(prev.code[1]);
|
||||
vector = input.witness;
|
||||
len = vector.length;
|
||||
dummy = new Buffer([]);
|
||||
@ -393,7 +394,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
signature = this.createSignature(index, prev, addr.key, type, version);
|
||||
|
||||
// Add signatures.
|
||||
if (bcoin.script.isPubkey(prev)) {
|
||||
if (prev.isPubkey()) {
|
||||
// P2PK
|
||||
|
||||
// Already signed.
|
||||
@ -401,7 +402,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
return true;
|
||||
|
||||
// Make sure the pubkey is ours.
|
||||
if (!utils.isEqual(addr.publicKey, prev[0]))
|
||||
if (!utils.isEqual(addr.publicKey, prev.code[0]))
|
||||
return false;
|
||||
|
||||
vector[0] = signature;
|
||||
@ -409,7 +410,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bcoin.script.isPubkeyhash(prev)) {
|
||||
if (prev.isPubkeyhash()) {
|
||||
// P2PKH
|
||||
|
||||
// Already signed.
|
||||
@ -417,7 +418,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
return true;
|
||||
|
||||
// Make sure the pubkey hash is ours.
|
||||
if (!utils.isEqual(addr.keyHash, prev[2]))
|
||||
if (!utils.isEqual(addr.keyHash, prev.code[2]))
|
||||
return false;
|
||||
|
||||
vector[0] = signature;
|
||||
@ -425,18 +426,18 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bcoin.script.isMultisig(prev)) {
|
||||
if (prev.isMultisig()) {
|
||||
// Multisig
|
||||
|
||||
// Grab the redeem script's keys to figure
|
||||
// out where our key should go.
|
||||
keys = prev.slice(1, -2);
|
||||
keys = prev.code.slice(1, -2);
|
||||
|
||||
// Grab `m` value (number of sigs required).
|
||||
m = prev[0];
|
||||
m = prev.code[0];
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = prev[prev.length - 2];
|
||||
n = prev.code[prev.code.length - 2];
|
||||
} else {
|
||||
// Only allow non-standard signing for
|
||||
// scripthash.
|
||||
@ -445,9 +446,9 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
|
||||
keys = [];
|
||||
|
||||
for (i = 0; i < prev.length; i++) {
|
||||
if (bcoin.script.isKey(prev[i]))
|
||||
keys.push(prev[i]);
|
||||
for (i = 0; i < prev.code.length; i++) {
|
||||
if (bcoin.script.isKey(prev.code[i]))
|
||||
keys.push(prev.code[i]);
|
||||
}
|
||||
|
||||
// We don't know what m is, so
|
||||
@ -573,7 +574,7 @@ MTX.prototype.addOutput = function addOutput(obj, value) {
|
||||
this.outputs.push(output);
|
||||
|
||||
if (options.script)
|
||||
output.script = options.script.slice();
|
||||
output.script = options.script.clone();
|
||||
|
||||
this.scriptOutput(this.outputs.length - 1, options);
|
||||
|
||||
@ -629,10 +630,7 @@ MTX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
} else if (options.key) {
|
||||
// P2PK Transaction
|
||||
// [pubkey] checksig
|
||||
script = [
|
||||
utils.ensureBuffer(options.key),
|
||||
'checksig'
|
||||
];
|
||||
script = bcoin.script.createPubkey(utils.ensureBuffer(options.key));
|
||||
} else if (options.flags) {
|
||||
// Nulldata Transaction
|
||||
// return [data]
|
||||
@ -648,13 +646,13 @@ MTX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
// hash160 [hash] eq
|
||||
if (options.scriptHash) {
|
||||
if (options.locktime != null) {
|
||||
script = [
|
||||
script = new Script([
|
||||
bcoin.script.array(options.locktime),
|
||||
'checklocktimeverify',
|
||||
'drop'
|
||||
].concat(script);
|
||||
].concat(script.code));
|
||||
}
|
||||
hash = utils.ripesha(bcoin.script.encode(script));
|
||||
hash = utils.ripesha(bcoin.script.encode(script.code));
|
||||
script = bcoin.script.createScripthash(hash);
|
||||
}
|
||||
|
||||
@ -668,7 +666,7 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
||||
|
||||
// Create copy with 0-script inputs
|
||||
for (i = 0; i < copy.inputs.length; i++) {
|
||||
copy.inputs[i].script = [];
|
||||
copy.inputs[i].script = new Script([]);
|
||||
copy.inputs[i].witness = [];
|
||||
}
|
||||
|
||||
@ -687,50 +685,48 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
||||
|
||||
// If we have access to the redeem script,
|
||||
// we can use it to calculate size much easier.
|
||||
if (this.inputs[i].script.length && bcoin.script.isScripthash(prev)) {
|
||||
if (this.inputs[i].script.code.length && prev.isScripthash()) {
|
||||
// Need to add the redeem script size
|
||||
// here since it will be ignored by
|
||||
// the isMultisig clause.
|
||||
// OP_PUSHDATA2 [redeem]
|
||||
prev = this.inputs[i].script[this.inputs[i].script.length - 1];
|
||||
size += utils.sizeIntv(prev.length) + prev.length;
|
||||
prev = bcoin.script.decode(prev);
|
||||
prev = this.inputs[i].getRedeem();
|
||||
size += utils.sizeIntv(prev.getSize()) + prev.getSize();
|
||||
}
|
||||
|
||||
if (bcoin.script.isWitnessProgram(prev)) {
|
||||
if (prev.isWitnessProgram()) {
|
||||
witness = true;
|
||||
// Now calculating vsize. The regular
|
||||
// redeem script (if there was one)
|
||||
// is now worth 4 points.
|
||||
size *= 4;
|
||||
if (this.inputs[i].witness.length && bcoin.script.isWitnessScripthash(prev)) {
|
||||
prev = this.inputs[i].witness[this.inputs[i].witness.length - 1];
|
||||
size += utils.sizeIntv(prev.length) + prev.length;
|
||||
prev = bcoin.script.decode(prev);
|
||||
} else if (bcoin.script.isWitnessPubkeyhash(prev)) {
|
||||
prev = bcoin.script.createPubkeyhash(prev[1]);
|
||||
if (this.inputs[i].witness.length && prev.isWitnessScripthash()) {
|
||||
prev = bcoin.script.getRedeem(this.inputs[i].witness);
|
||||
size += utils.sizeIntv(prev.getSize()) + prev.getSize();
|
||||
} else if (prev.isWitnessPubkeyhash()) {
|
||||
prev = bcoin.script.createPubkeyhash(prev.code[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (bcoin.script.isPubkey(prev)) {
|
||||
if (prev.isPubkey()) {
|
||||
// P2PK
|
||||
// OP_PUSHDATA0 [signature]
|
||||
size += 1 + 73;
|
||||
} else if (bcoin.script.isPubkeyhash(prev)) {
|
||||
} else if (prev.isPubkeyhash()) {
|
||||
// P2PKH
|
||||
// OP_PUSHDATA0 [signature]
|
||||
size += 1 + 73;
|
||||
// OP_PUSHDATA0 [key]
|
||||
size += 1 + 33;
|
||||
} else if (bcoin.script.isMultisig(prev)) {
|
||||
} else if (prev.isMultisig()) {
|
||||
// Bare Multisig
|
||||
// Get the previous m value:
|
||||
m = prev[0];
|
||||
m = prev.code[0];
|
||||
// OP_0
|
||||
size += 1;
|
||||
// OP_PUSHDATA0 [signature] ...
|
||||
size += (1 + 73) * m;
|
||||
} else if (bcoin.script.isScripthash(prev)) {
|
||||
} else if (prev.isScripthash()) {
|
||||
// P2SH Multisig
|
||||
// This technically won't work well for other
|
||||
// kinds of P2SH. It will also over-estimate
|
||||
@ -760,8 +756,8 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
||||
size += 1;
|
||||
} else {
|
||||
// OP_PUSHDATA0 [signature]
|
||||
for (j = 0; j < prev.length; j++) {
|
||||
if (bcoin.script.isKey(prev[j]))
|
||||
for (j = 0; j < prev.code.length; j++) {
|
||||
if (bcoin.script.isKey(prev.code[j]))
|
||||
size += 1 + 73;
|
||||
}
|
||||
}
|
||||
@ -986,8 +982,8 @@ MTX.prototype.sortMembers = function sortMembers() {
|
||||
if (res !== 0)
|
||||
return res;
|
||||
|
||||
a = bcoin.script.encode(a.script);
|
||||
b = bcoin.script.encode(b.script);
|
||||
a = a.encode();
|
||||
b = b.encode();
|
||||
|
||||
return utils.cmp(a, b);
|
||||
});
|
||||
|
||||
@ -9,6 +9,7 @@ var bcoin = require('../bcoin');
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.protocol.constants;
|
||||
var Script = bcoin.script;
|
||||
|
||||
/**
|
||||
* Output
|
||||
@ -30,7 +31,7 @@ function Output(options, tx) {
|
||||
}
|
||||
|
||||
this.value = utils.satoshi(value || new bn(0));
|
||||
this.script = options.script || [];
|
||||
this.script = options.script || new Script([]);
|
||||
this._size = options._size || 0;
|
||||
this._offset = options._offset || 0;
|
||||
this._mutable = !tx || (tx instanceof bcoin.mtx);
|
||||
@ -57,7 +58,7 @@ Output.prototype.getType = function getType() {
|
||||
if (this._type)
|
||||
return this._type;
|
||||
|
||||
type = bcoin.script.getOutputType(this.script);
|
||||
type = this.script.getType();
|
||||
|
||||
if (!this._mutable)
|
||||
this._type = type;
|
||||
@ -71,7 +72,7 @@ Output.prototype.getAddress = function getAddress() {
|
||||
if (this._address)
|
||||
return this._address;
|
||||
|
||||
address = bcoin.script.getOutputAddress(this.script);
|
||||
address = this.script.getAddress();
|
||||
|
||||
if (!this._mutable)
|
||||
this._address = address;
|
||||
@ -101,28 +102,12 @@ Output.prototype.test = function test(addressTable) {
|
||||
return false;
|
||||
};
|
||||
|
||||
Output.prototype.getSigops = function getSigops(accurate) {
|
||||
return bcoin.script.getSigops(this.script, accurate);
|
||||
};
|
||||
|
||||
Output.prototype.getID = function getID() {
|
||||
var data = bcoin.script.encode(this.script);
|
||||
var data = this.script.encode();
|
||||
var hash = utils.toHex(utils.ripesha(data));
|
||||
return '[' + this.type + ':' + hash.slice(0, 7) + ']';
|
||||
};
|
||||
|
||||
Output.prototype.getData = function getData() {
|
||||
var def;
|
||||
|
||||
def = {
|
||||
side: 'output',
|
||||
value: this.value,
|
||||
script: this.script
|
||||
};
|
||||
|
||||
return utils.merge(def, bcoin.script.getOutputData(this.script));
|
||||
};
|
||||
|
||||
Output.prototype.inspect = function inspect() {
|
||||
return {
|
||||
type: this.getType(),
|
||||
@ -135,14 +120,14 @@ Output.prototype.inspect = function inspect() {
|
||||
Output.prototype.toJSON = function toJSON() {
|
||||
return {
|
||||
value: utils.btc(this.value),
|
||||
script: utils.toHex(bcoin.script.encode(this.script))
|
||||
script: utils.toHex(this.script.encode())
|
||||
};
|
||||
};
|
||||
|
||||
Output._fromJSON = function _fromJSON(json) {
|
||||
return {
|
||||
value: utils.satoshi(json.value),
|
||||
script: bcoin.script.decode(new Buffer(json.script, 'hex'))
|
||||
script: new Script(new Buffer(json.script, 'hex'))
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -380,18 +380,16 @@ Framer._getBlocks = function _getBlocks(hashes, stop) {
|
||||
|
||||
Framer.input = function _input(input) {
|
||||
var off = 0;
|
||||
var s, p;
|
||||
var script, p;
|
||||
|
||||
s = bcoin.script.encode(input.script);
|
||||
p = new Buffer(32 + 4 + utils.sizeIntv(s.length) + s.length + 4);
|
||||
script = input.script.encode();
|
||||
p = new Buffer(32 + 4 + utils.sizeIntv(script.length) + script.length + 4);
|
||||
|
||||
off += utils.copy(new Buffer(input.prevout.hash, 'hex'), p, off);
|
||||
off += utils.writeU32(p, input.prevout.index, off);
|
||||
|
||||
off += utils.writeIntv(p, s.length, off);
|
||||
if (!s.copy)
|
||||
console.log(s);
|
||||
off += utils.copy(s, p, off);
|
||||
off += utils.writeIntv(p, script.length, off);
|
||||
off += utils.copy(script, p, off);
|
||||
|
||||
off += utils.writeU32(p, input.sequence, off);
|
||||
|
||||
@ -400,23 +398,23 @@ Framer.input = function _input(input) {
|
||||
|
||||
Framer.output = function _output(output) {
|
||||
var off = 0;
|
||||
var s, p;
|
||||
var script, p;
|
||||
|
||||
s = bcoin.script.encode(output.script);
|
||||
p = new Buffer(8 + utils.sizeIntv(s.length) + s.length);
|
||||
script = output.script.encode();
|
||||
p = new Buffer(8 + utils.sizeIntv(script.length) + script.length);
|
||||
|
||||
off += utils.write64(p, output.value, off);
|
||||
assert(output.value.byteLength() <= 8);
|
||||
|
||||
off += utils.writeIntv(p, s.length, off);
|
||||
off += utils.copy(s, p, off);
|
||||
off += utils.writeIntv(p, script.length, off);
|
||||
off += utils.copy(script, p, off);
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
Framer.utxo =
|
||||
Framer.coin = function _coin(coin, extended) {
|
||||
var script = bcoin.script.encode(coin.script);
|
||||
var script = coin.script.encode();
|
||||
var intSize = utils.sizeIntv(script.length);
|
||||
var height = coin.height;
|
||||
var off = 0;
|
||||
|
||||
@ -356,7 +356,7 @@ Parser.parseBlockCompact = function parseBlockCompact(p) {
|
||||
var height = -1;
|
||||
var version, prevBlock, merkleRoot, ts, bits, nonce;
|
||||
var i, totalTX, tx;
|
||||
var inCount, input, s, raw;
|
||||
var inCount, input, raw;
|
||||
|
||||
p = new BufferReader(p);
|
||||
p.start();
|
||||
@ -379,9 +379,8 @@ Parser.parseBlockCompact = function parseBlockCompact(p) {
|
||||
}
|
||||
|
||||
if (input) {
|
||||
s = input.script;
|
||||
if (Buffer.isBuffer(s[0]))
|
||||
height = s[0];
|
||||
if (Buffer.isBuffer(input.script.code[0]))
|
||||
height = input.script.code[0];
|
||||
}
|
||||
|
||||
raw = p.data;
|
||||
@ -411,7 +410,7 @@ Parser.parseInput = function parseInput(p) {
|
||||
|
||||
hash = p.readHash();
|
||||
index = p.readU32();
|
||||
script = bcoin.script.decode(p.readVarBytes());
|
||||
script = new bcoin.script(p.readVarBytes());
|
||||
sequence = p.readU32();
|
||||
|
||||
return {
|
||||
@ -432,7 +431,7 @@ Parser.parseOutput = function parseOutput(p) {
|
||||
p.start();
|
||||
|
||||
value = p.read64();
|
||||
script = bcoin.script.decode(p.readVarBytes());
|
||||
script = new bcoin.script(p.readVarBytes());
|
||||
|
||||
return {
|
||||
_size: p.end(),
|
||||
@ -443,6 +442,7 @@ Parser.parseOutput = function parseOutput(p) {
|
||||
|
||||
Parser.parseCoin = function parseCoin(p, extended) {
|
||||
var version, height, value, script, hash, index, spent;
|
||||
|
||||
p = new BufferReader(p);
|
||||
|
||||
version = p.readU32();
|
||||
@ -453,12 +453,12 @@ Parser.parseCoin = function parseCoin(p, extended) {
|
||||
|
||||
value = p.read64();
|
||||
|
||||
script = bcoin.script.decode(p.readVarBytes());
|
||||
script = new bcoin.script(p.readVarBytes());
|
||||
|
||||
if (extended) {
|
||||
hash = p.readHash();
|
||||
index = p.readU32();
|
||||
spent = p.readU8();
|
||||
spent = p.readU8() === 1;
|
||||
} else {
|
||||
hash = utils.slice(constants.zeroHash);
|
||||
index = 0xffffffff;
|
||||
@ -527,7 +527,7 @@ Parser.isWitnessTX = function isWitnessTX(p) {
|
||||
if (p.left() < 12)
|
||||
return false;
|
||||
|
||||
return p[p.offset + 4] === 0 && p[p.offset + 5] !== 0;
|
||||
return p.data[p.offset + 4] === 0 && p.data[p.offset + 5] !== 0;
|
||||
};
|
||||
|
||||
Parser.parseWitnessTX = function parseWitnessTX(p) {
|
||||
@ -822,7 +822,7 @@ BufferReader.prototype.read64BE = function read64BE() {
|
||||
};
|
||||
|
||||
BufferReader.prototype.readBytes = function readBytes(size) {
|
||||
assert(size > 0)
|
||||
assert(size >= 0);
|
||||
assert(this.offset + size <= this.data.length);
|
||||
var ret = utils.slice(this.data, this.offset, this.offset + size);
|
||||
this.offset += size;
|
||||
@ -830,7 +830,7 @@ BufferReader.prototype.readBytes = function readBytes(size) {
|
||||
};
|
||||
|
||||
BufferReader.prototype.readString = function readString(enc, size) {
|
||||
assert(size > 0)
|
||||
assert(size >= 0);
|
||||
assert(this.offset + size <= this.data.length);
|
||||
var ret = this.data.toString(enc, this.offset, this.offset + size);
|
||||
this.offset += size;
|
||||
|
||||
@ -10,6 +10,7 @@ var bcoin = require('../bcoin');
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var constants = bcoin.protocol.constants;
|
||||
var Script = bcoin.script;
|
||||
|
||||
/**
|
||||
* TX
|
||||
@ -172,19 +173,6 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
TX.prototype.getSubscript = function getSubscript(index) {
|
||||
var script;
|
||||
|
||||
if (typeof index !== 'number')
|
||||
index = this.outputs.indexOf(index);
|
||||
|
||||
assert(this.outputs[index]);
|
||||
|
||||
script = this.outputs[index].script;
|
||||
|
||||
return bcoin.script.getSubscript(script);
|
||||
};
|
||||
|
||||
TX.prototype.signatureHash = function signatureHash(index, s, type, version) {
|
||||
assert(version >= 0 && version <= 1);
|
||||
if (version === 0)
|
||||
@ -206,7 +194,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, s, type) {
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
copy.inputs.push({
|
||||
prevout: this.inputs[i].prevout,
|
||||
script: this.inputs[i].script.slice(),
|
||||
script: this.inputs[i].script.clone(),
|
||||
witness: this.inputs[i].witness.slice(),
|
||||
sequence: this.inputs[i].sequence
|
||||
});
|
||||
@ -215,7 +203,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, s, type) {
|
||||
for (i = 0; i < this.outputs.length; i++) {
|
||||
copy.outputs.push({
|
||||
value: this.outputs[i].value,
|
||||
script: this.outputs[i].script.slice()
|
||||
script: this.outputs[i].script.clone()
|
||||
});
|
||||
}
|
||||
|
||||
@ -226,7 +214,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, s, type) {
|
||||
type = constants.hashType[type];
|
||||
|
||||
assert(index >= 0 && index < copy.inputs.length)
|
||||
assert(Array.isArray(s));
|
||||
assert(s instanceof bcoin.script);
|
||||
|
||||
// Disable this for now. We allow null hash types
|
||||
// because bitcoind allows empty signatures. On
|
||||
@ -236,7 +224,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, s, type) {
|
||||
|
||||
// Remove all signatures.
|
||||
for (i = 0; i < copy.inputs.length; i++)
|
||||
copy.inputs[i].script = [];
|
||||
copy.inputs[i].script = new Script([]);
|
||||
|
||||
// Set our input to previous output's script
|
||||
copy.inputs[index].script = s;
|
||||
@ -262,7 +250,7 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, s, type) {
|
||||
// Null outputs that are not the at current input index.
|
||||
for (i = 0; i < copy.outputs.length; i++) {
|
||||
if (i !== index) {
|
||||
copy.outputs[i].script = [];
|
||||
copy.outputs[i].script = new Script([]);
|
||||
copy.outputs[i].value = new bn('ffffffffffffffff', 'hex');
|
||||
}
|
||||
}
|
||||
@ -302,7 +290,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, s, type) {
|
||||
type = constants.hashType[type];
|
||||
|
||||
assert(index >= 0 && index < this.inputs.length)
|
||||
assert(Array.isArray(s));
|
||||
assert(s instanceof bcoin.script);
|
||||
|
||||
if (!(type & constants.hashType.anyonecanpay)) {
|
||||
hashPrevouts = new Buffer(36 * this.inputs.length);
|
||||
@ -353,7 +341,7 @@ TX.prototype.signatureHashV1 = function signatureHashV1(index, s, type) {
|
||||
hashOutputs.fill(0);
|
||||
}
|
||||
|
||||
s = bcoin.script.encode(s);
|
||||
s = s.encode();
|
||||
|
||||
msg = new Buffer(
|
||||
4 + 32 + 32 + 36
|
||||
@ -666,23 +654,23 @@ TX.prototype._getSigops = function _getSigops(scriptHash, accurate) {
|
||||
|
||||
prev = input.output.script;
|
||||
|
||||
total += bcoin.script.getSigops(input.script, accurate);
|
||||
total += input.script.getSigops(accurate);
|
||||
|
||||
if (scriptHash && !this.isCoinbase()) {
|
||||
if (!bcoin.script.isScripthash(prev))
|
||||
if (!prev.isScripthash())
|
||||
return;
|
||||
|
||||
if (!bcoin.script.isPushOnly(input.script))
|
||||
if (!input.script.isPushOnly())
|
||||
return;
|
||||
|
||||
prev = bcoin.script.getRedeem(input.script);
|
||||
prev = input.script.getRedeem();
|
||||
|
||||
total += bcoin.script.getSigops(prev, true);
|
||||
total += prev.getSigops(true);
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.outputs.forEach(function(output) {
|
||||
total += bcoin.script.getSigops(output.script, accurate);
|
||||
total += output.script.getSigops(accurate);
|
||||
}, this);
|
||||
|
||||
return total;
|
||||
@ -699,19 +687,19 @@ TX.prototype.getSigops = function getSigops(scriptHash, accurate) {
|
||||
|
||||
prev = input.output.script;
|
||||
|
||||
if (bcoin.script.isScripthash(prev))
|
||||
prev = bcoin.script.getRedeem(input.script);
|
||||
if (prev.isScripthash())
|
||||
prev = input.script.getRedeem();
|
||||
|
||||
if (bcoin.script.isWitnessScripthash(prev)) {
|
||||
if (prev.isWitnessScripthash()) {
|
||||
prev = bcoin.script.getRedeem(input.witness);
|
||||
cost += bcoin.script.getSigops(prev, true);
|
||||
cost += prev.getSigops(true);
|
||||
} else {
|
||||
cost += 0;
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.outputs.forEach(function(output) {
|
||||
if (bcoin.script.isWitnessPubkeyhash(output.script))
|
||||
if (output.script.isWitnessPubkeyhash())
|
||||
cost += 1;
|
||||
else
|
||||
cost += 0;
|
||||
@ -736,7 +724,7 @@ TX.prototype.isStandard = function isStandard(flags) {
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
if (bcoin.script.getSize(input.script) > 1650)
|
||||
if (input.script.getSize() > 1650)
|
||||
return false;
|
||||
|
||||
// Not accurate?
|
||||
@ -744,16 +732,16 @@ TX.prototype.isStandard = function isStandard(flags) {
|
||||
continue;
|
||||
|
||||
if (flags & constants.flags.VERIFY_SIGPUSHONLY) {
|
||||
if (!bcoin.script.isPushOnly(input.script))
|
||||
if (!input.script.isPushOnly())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < this.outputs.length; i++) {
|
||||
output = this.outputs[i];
|
||||
type = bcoin.script.getType(output.script);
|
||||
type = output.script.getType();
|
||||
|
||||
if (!bcoin.script.isStandard(output.script))
|
||||
if (!output.script.isStandard())
|
||||
return false;
|
||||
|
||||
if (type === 'unknown')
|
||||
@ -793,7 +781,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||
if (!input.output)
|
||||
return false;
|
||||
|
||||
args = bcoin.script.getArgs(input.output.script);
|
||||
args = input.output.script.getArgs();
|
||||
|
||||
if (args < 0)
|
||||
return false;
|
||||
@ -803,10 +791,10 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||
// Bitcoind doesn't do this, but it's possible someone
|
||||
// could DoS us by sending ridiculous txs to the mempool
|
||||
// if we don't put this here.
|
||||
if (!bcoin.script.isPushOnly(input.script))
|
||||
if (!input.script.isPushOnly())
|
||||
return false;
|
||||
|
||||
res = bcoin.script.execute(input.script, stack, this, i, flags);
|
||||
res = input.script.execute(stack, this, i, flags);
|
||||
|
||||
// TODO: Segwit here.
|
||||
|
||||
@ -814,29 +802,27 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||
return false;
|
||||
|
||||
if ((flags & constants.flags.VERIFY_P2SH)
|
||||
&& bcoin.script.isScripthash(input.output.script)) {
|
||||
&& input.output.script.isScripthash()) {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
|
||||
redeem = stack.pop();
|
||||
redeem = bcoin.script.getRedeem(stack);
|
||||
|
||||
if (!Buffer.isBuffer(redeem))
|
||||
if (!redeem)
|
||||
return false;
|
||||
|
||||
// Not accurate?
|
||||
if (redeem.length > 520)
|
||||
if (redeem.getSize() > 520)
|
||||
return false;
|
||||
|
||||
redeem = bcoin.script.decode(redeem);
|
||||
|
||||
// Also consider scripthash "unknown"?
|
||||
if (bcoin.script.getType(redeem) === 'unknown') {
|
||||
if (bcoin.script.getSigops(redeem, true) > maxSigops)
|
||||
if (redeem.getType() === 'unknown') {
|
||||
if (redeem.getSigops(true) > maxSigops)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
targs = bcoin.script.getArgs(redeem);
|
||||
targs = redeem.getArgs();
|
||||
if (targs < 0)
|
||||
return false;
|
||||
args += targs;
|
||||
@ -942,11 +928,11 @@ TX.prototype.getValue = function getValue() {
|
||||
|
||||
TX.prototype.hasType = function hasType(type) {
|
||||
for (var i = 0; i < this.inputs.length; i++) {
|
||||
if (bcoin.script.getInputType(this.inputs[i].script) === type)
|
||||
if (this.inputs[i].getInputType() === type)
|
||||
return true;
|
||||
}
|
||||
for (var i = 0; i < this.outputs.length; i++) {
|
||||
if (bcoin.script.getType(this.outputs[i].script) === type)
|
||||
if (this.outputs[i].getType() === type)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -179,6 +179,6 @@ describe('Protocol', function() {
|
||||
'de5c0500000017a9141d9ca71efa36d814424ea6ca1437e67287aebe348' +
|
||||
'700000000', 'hex');
|
||||
var tx = bcoin.protocol.parser.parseTX(rawTwoTxs);
|
||||
assert.deepEqual(tx._raw, rawFirstTx);
|
||||
assert.deepEqual(bcoin.protocol.framer.tx(tx), rawFirstTx);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
var assert = require('assert');
|
||||
var bcoin = require('../');
|
||||
var Script = bcoin.script;
|
||||
|
||||
describe('Script', function() {
|
||||
it('should encode/decode script', function() {
|
||||
@ -34,55 +35,55 @@ describe('Script', function() {
|
||||
it('should recognize a P2SH output', function () {
|
||||
var hex = 'a91419a7d869032368fd1f1e26e5e73a4ad0e474960e87'
|
||||
var encoded = new Buffer(hex, 'hex')
|
||||
var decoded = bcoin.script.decode(encoded);
|
||||
assert(bcoin.script.isScripthash(decoded))
|
||||
var decoded = new bcoin.script(encoded);
|
||||
assert(decoded.isScripthash())
|
||||
})
|
||||
|
||||
it('should recognize a Null Data output', function () {
|
||||
var hex = '6a28590c080112220a1b353930632e6f7267282a5f5e294f7665726c6179404f7261636c65103b1a010c'
|
||||
var encoded = new Buffer(hex, 'hex')
|
||||
var decoded = bcoin.script.decode(encoded);
|
||||
assert(bcoin.script.isNulldata(decoded))
|
||||
var decoded = new Script(encoded);
|
||||
assert(decoded.isNulldata())
|
||||
})
|
||||
|
||||
it('should handle if statements correctly', function () {
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [2, 'equal', 'if', 3, 'else', 4, 'endif', 5];
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([2, 'equal', 'if', 3, 'else', 4, 'endif', 5]);
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [9, 'equal', 'if', 3, 'else', 4, 'endif', 5];
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([9, 'equal', 'if', 3, 'else', 4, 'endif', 5]);
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [4], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [2, 'equal', 'if', 3, 'endif', 5];
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([2, 'equal', 'if', 3, 'endif', 5]);
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [9, 'equal', 'if', 3, 'endif', 5];
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([9, 'equal', 'if', 3, 'endif', 5]);
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [9, 'equal', 'notif', 3, 'endif', 5];
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([9, 'equal', 'notif', 3, 'endif', 5]);
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
})
|
||||
|
||||
@ -13,12 +13,12 @@ var dummyInput = {
|
||||
version: 1,
|
||||
height: 0,
|
||||
value: constants.maxMoney.clone(),
|
||||
script: [],
|
||||
script: new bcoin.script([]),
|
||||
hash: constants.zeroHash,
|
||||
index: 0,
|
||||
spent: false
|
||||
},
|
||||
script: [],
|
||||
script: new bcoin.script([]),
|
||||
sequence: 0xffffffff
|
||||
};
|
||||
|
||||
@ -167,7 +167,7 @@ describe('Wallet', function() {
|
||||
// Script inputs but do not sign
|
||||
w.scriptInputs(fake);
|
||||
// Fake signature
|
||||
fake.inputs[0].script[0] = new Buffer([0,0,0,0,0,0,0,0,0]);
|
||||
fake.inputs[0].script.code[0] = new Buffer([0,0,0,0,0,0,0,0,0]);
|
||||
// balance: 11000
|
||||
|
||||
// Just for debugging
|
||||
@ -459,6 +459,8 @@ describe('Wallet', function() {
|
||||
send.addOutput({ address: receive.getAddress(), value: 5460 });
|
||||
assert(!send.verify(null, true, flags));
|
||||
w1.fill(send, { m: w1.m, n: w1.n }, function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
assert(!err);
|
||||
|
||||
w1.sign(send);
|
||||
@ -499,7 +501,7 @@ describe('Wallet', function() {
|
||||
if (witness)
|
||||
send.inputs[0].witness[2] = new Buffer([]);
|
||||
else
|
||||
send.inputs[0].script[2] = 0;
|
||||
send.inputs[0].script.code[2] = 0;
|
||||
|
||||
assert(!send.verify(null, true, flags));
|
||||
assert.equal(send.getFee().toNumber(), 10000);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user