sign unknown txs.
This commit is contained in:
parent
b1d46206a8
commit
b9041a0157
@ -1405,9 +1405,7 @@ script.isNulldata = function isNulldata(s) {
|
|||||||
if (s.length !== 2)
|
if (s.length !== 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
res = s[0] === 'ret'
|
res = s[0] === 'ret' && script.isData(s[1]);
|
||||||
&& Array.isArray(s[1])
|
|
||||||
&& s[1].length <= constants.script.maxOpReturn;
|
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
@ -1659,6 +1657,10 @@ script.isCoinbase = function isCoinbase(s, block, strict) {
|
|||||||
return coinbase;
|
return coinbase;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Detect script array types. Note: these functions
|
||||||
|
// are not mutually exclusive. Only use for
|
||||||
|
// verification, not detection.
|
||||||
|
|
||||||
script.isHash = function isHash(hash) {
|
script.isHash = function isHash(hash) {
|
||||||
if (!utils.isBuffer(hash))
|
if (!utils.isBuffer(hash))
|
||||||
return false;
|
return false;
|
||||||
@ -1683,6 +1685,20 @@ script.isSignature = function isSignature(sig, allowZero) {
|
|||||||
return sig.length >= 9 && sig.length <= 73;
|
return sig.length >= 9 && sig.length <= 73;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script.isEmpty = function isEmpty(data) {
|
||||||
|
if (!utils.isBuffer(data))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return data.length === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
script.isData = function isData(data) {
|
||||||
|
if (!utils.isBuffer(data))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return data.length <= constants.script.maxOpReturn;
|
||||||
|
};
|
||||||
|
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
|
// https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
|
||||||
/**
|
/**
|
||||||
* A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
|
* A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
|
||||||
|
|||||||
208
lib/bcoin/tx.js
208
lib/bcoin/tx.js
@ -189,7 +189,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
|||||||
// P2PKH
|
// P2PKH
|
||||||
input.script = [ [], pub ];
|
input.script = [ [], pub ];
|
||||||
} else if (bcoin.script.isMultisig(s)) {
|
} else if (bcoin.script.isMultisig(s)) {
|
||||||
// Bare Multisig
|
// Multisig
|
||||||
// Technically we should create m signature slots,
|
// Technically we should create m signature slots,
|
||||||
// but we create n signature slots so we can order
|
// but we create n signature slots so we can order
|
||||||
// the signatures properly.
|
// the signatures properly.
|
||||||
@ -201,6 +201,12 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
|||||||
// Fill script with `n` signature slots.
|
// Fill script with `n` signature slots.
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
input.script[i + 1] = [];
|
input.script[i + 1] = [];
|
||||||
|
} else {
|
||||||
|
// Likely a non-standard scripthash multisig
|
||||||
|
// input. Just set up the empty array. Also,
|
||||||
|
// only allow nonstandard types for scripthash.
|
||||||
|
if (redeem)
|
||||||
|
input.script = [ [] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
// P2SH requires the redeem script after signatures
|
// P2SH requires the redeem script after signatures
|
||||||
@ -313,7 +319,9 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
input.script[0] = signature;
|
input.script[0] = signature;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (bcoin.script.isPubkeyhash(s)) {
|
}
|
||||||
|
|
||||||
|
if (bcoin.script.isPubkeyhash(s)) {
|
||||||
// P2PKH
|
// P2PKH
|
||||||
|
|
||||||
// Something is wrong. Abort.
|
// Something is wrong. Abort.
|
||||||
@ -331,100 +339,134 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
input.script[0] = signature;
|
input.script[0] = signature;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (bcoin.script.isMultisig(s)) {
|
}
|
||||||
|
|
||||||
|
if (bcoin.script.isMultisig(s)) {
|
||||||
// Multisig
|
// Multisig
|
||||||
|
|
||||||
|
// Grab the redeem script's keys to figure
|
||||||
|
// out where our key should go.
|
||||||
|
keys = s.slice(1, -2);
|
||||||
|
|
||||||
// Grab `m` value (number of sigs required).
|
// Grab `m` value (number of sigs required).
|
||||||
m = s[0];
|
m = s[0];
|
||||||
|
|
||||||
// Grab `n` value (number of keys).
|
// Grab `n` value (number of keys).
|
||||||
n = s[s.length - 2];
|
n = s[s.length - 2];
|
||||||
|
} else {
|
||||||
// Something is very wrong here. Abort.
|
// Only allow non-standard signing for
|
||||||
if (len - 1 > n)
|
// scripthash.
|
||||||
|
if (len !== input.script.length - 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Count the number of current signatures.
|
keys = [];
|
||||||
signatures = 0;
|
|
||||||
for (i = 1; i < len; i++) {
|
for (i = 0; i < s.length; i++) {
|
||||||
if (Array.isArray(input.script[i]) && input.script[i].length)
|
if (bcoin.script.isKey(s[i]))
|
||||||
signatures++;
|
keys.push(s[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signatures are already finalized.
|
n = keys.length;
|
||||||
if (signatures === m && len - 1 === m)
|
m = n;
|
||||||
return true;
|
|
||||||
|
|
||||||
// This can happen in a case where another
|
|
||||||
// implementation adds signatures willy-nilly
|
|
||||||
// or by `m`. Add some signature slots for
|
|
||||||
// us to use.
|
|
||||||
while (len - 1 < n) {
|
|
||||||
input.script.splice(len, 0, []);
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the redeem script's keys to figure
|
|
||||||
// out where our key should go.
|
|
||||||
keys = s.slice(1, -2);
|
|
||||||
|
|
||||||
// Find the key index so we can place
|
|
||||||
// the signature in the same index.
|
|
||||||
for (ki = 0; ki < keys.length; ki++) {
|
|
||||||
if (utils.isEqual(pub, keys[ki]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Our public key is not in the prev_out
|
|
||||||
// script. We tried to sign a transaction
|
|
||||||
// that is not redeemable by us.
|
|
||||||
if (ki === keys.length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Offset key index by one to turn it into
|
|
||||||
// "sig index". Accounts for OP_0 byte at
|
|
||||||
// the start.
|
|
||||||
ki++;
|
|
||||||
|
|
||||||
// Add our signature to the correct slot
|
|
||||||
// and increment the total number of
|
|
||||||
// signatures.
|
|
||||||
if (ki < len && signatures < m) {
|
|
||||||
if (Array.isArray(input.script[ki]) && !input.script[ki].length) {
|
|
||||||
input.script[ki] = signature;
|
|
||||||
signatures++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// All signatures added. Finalize.
|
|
||||||
if (signatures >= m) {
|
|
||||||
// Remove empty slots left over.
|
|
||||||
for (i = len - 1; i >= 1; i--) {
|
|
||||||
if (Array.isArray(input.script[i]) && !input.script[i].length) {
|
|
||||||
input.script.splice(i, 1);
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove signatures which are not required.
|
|
||||||
// This should never happen except when dealing
|
|
||||||
// with implementations that potentially handle
|
|
||||||
// signature slots differently.
|
|
||||||
while (signatures > m) {
|
|
||||||
input.script.splice(len - 1, 1);
|
|
||||||
signatures--;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sanity checks.
|
|
||||||
assert.equal(signatures, m);
|
|
||||||
assert.equal(len - 1, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return signatures === m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
// Something is very wrong here. Abort.
|
||||||
|
if (len - 1 > n)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Count the number of current signatures.
|
||||||
|
signatures = 0;
|
||||||
|
for (i = 1; i < len; i++) {
|
||||||
|
if (bcoin.script.isSignature(input.script[i]))
|
||||||
|
signatures++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signatures are already finalized.
|
||||||
|
if (signatures === m && len - 1 === m)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// This can happen in a case where another
|
||||||
|
// implementation adds signatures willy-nilly
|
||||||
|
// or by `m`. Add some signature slots for
|
||||||
|
// us to use.
|
||||||
|
while (len - 1 < n) {
|
||||||
|
input.script.splice(len, 0, []);
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the key index so we can place
|
||||||
|
// the signature in the same index.
|
||||||
|
for (ki = 0; ki < keys.length; ki++) {
|
||||||
|
if (utils.isEqual(pub, keys[ki]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our public key is not in the prev_out
|
||||||
|
// script. We tried to sign a transaction
|
||||||
|
// that is not redeemable by us.
|
||||||
|
if (ki === keys.length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Offset key index by one to turn it into
|
||||||
|
// "sig index". Accounts for OP_0 byte at
|
||||||
|
// the start.
|
||||||
|
ki++;
|
||||||
|
|
||||||
|
// Add our signature to the correct slot
|
||||||
|
// and increment the total number of
|
||||||
|
// signatures.
|
||||||
|
if (ki < len && signatures < m) {
|
||||||
|
if (bcoin.script.isEmpty(input.script[ki])) {
|
||||||
|
input.script[ki] = signature;
|
||||||
|
signatures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All signatures added. Finalize.
|
||||||
|
if (signatures >= m) {
|
||||||
|
// Remove empty slots left over.
|
||||||
|
for (i = len - 1; i >= 1; i--) {
|
||||||
|
if (bcoin.script.isEmpty(input.script[i])) {
|
||||||
|
input.script.splice(i, 1);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove signatures which are not required.
|
||||||
|
// This should never happen except when dealing
|
||||||
|
// with implementations that potentially handle
|
||||||
|
// signature slots differently.
|
||||||
|
while (signatures > m) {
|
||||||
|
input.script.splice(len - 1, 1);
|
||||||
|
signatures--;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity checks.
|
||||||
|
assert.equal(signatures, m);
|
||||||
|
assert.equal(len - 1, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return signatures === m;
|
||||||
|
};
|
||||||
|
|
||||||
|
TX.prototype.finalize = function finalize() {
|
||||||
|
var i, input, s, len, j;
|
||||||
|
for (i = 0; i < this.inputs.length; i++) {
|
||||||
|
input = this.inputs[i];
|
||||||
|
s = input.out.tx.getSubscript(input.out.index);
|
||||||
|
len = s.length;
|
||||||
|
|
||||||
|
if (bcoin.script.isScripthash(s))
|
||||||
|
len--;
|
||||||
|
|
||||||
|
for (j = len - 1; j >= 1; j--) {
|
||||||
|
if (bcoin.script.isEmpty(input.script[j])) {
|
||||||
|
input.script.splice(j, 1);
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
|
TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
|
||||||
|
|||||||
@ -77,21 +77,59 @@ function Wallet(options, passphrase) {
|
|||||||
this.key = bcoin.ecdsa.genKeyPair();
|
this.key = bcoin.ecdsa.genKeyPair();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.type = 'pubkeyhash';
|
// Compatability
|
||||||
|
if (options.multisig) {
|
||||||
|
if (options.multisig.type)
|
||||||
|
options.type = options.multisig.type;
|
||||||
|
if (options.multisig.keys)
|
||||||
|
options.keys = options.multisig.keys;
|
||||||
|
if (options.multisig.m)
|
||||||
|
options.m = options.multisig.m;
|
||||||
|
if (options.multisig.n)
|
||||||
|
options.n = options.multisig.n;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.type = options.type || 'pubkeyhash';
|
||||||
|
this.subtype = options.subtype;
|
||||||
this.keys = [];
|
this.keys = [];
|
||||||
this.m = 1;
|
this.m = options.m || 1;
|
||||||
this.n = 1;
|
this.n = options.n || 1;
|
||||||
|
|
||||||
this.prefix = 'bt/wallet/' + this.getKeyAddress() + '/';
|
if (this.n > 1) {
|
||||||
|
if (this.type !== 'multisig')
|
||||||
|
this.type = 'scripthash';
|
||||||
|
if (this.type === 'scripthash')
|
||||||
|
this.subtype = 'multisig';
|
||||||
|
}
|
||||||
|
|
||||||
this.multisig(options.multisig || {});
|
if (network.prefixes[this.type] == null)
|
||||||
|
throw new Error('Unknown prefix: ' + this.type);
|
||||||
|
|
||||||
|
this.nmax = this.type === 'scripthash'
|
||||||
|
? (this.compressed ? 15 : 7)
|
||||||
|
: 3;
|
||||||
|
|
||||||
|
if (this.m < 1 || this.m > this.n)
|
||||||
|
throw new Error('m ranges between 1 and n');
|
||||||
|
|
||||||
|
if (this.n < 1 || this.n > this.nmax)
|
||||||
|
throw new Error('n ranges between 1 and ' + this.nmax);
|
||||||
|
|
||||||
|
this.addKey(this.getPublicKey());
|
||||||
|
|
||||||
|
(options.keys || []).forEach(function(key) {
|
||||||
|
this.addKey(key);
|
||||||
|
}, this);
|
||||||
|
|
||||||
if (this.redeem) {
|
if (this.redeem) {
|
||||||
if (!bcoin.script.isEncoded(this.redeem))
|
if (!bcoin.script.isEncoded(this.redeem))
|
||||||
this.redeem = bcoin.script.encode(this.redeem);
|
this.redeem = bcoin.script.encode(this.redeem);
|
||||||
this.type = 'scripthash';
|
this.type = 'scripthash';
|
||||||
|
this.subtype = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.prefix = 'bt/wallet/' + this.getKeyAddress() + '/';
|
||||||
|
|
||||||
this.tx = new bcoin.txPool(this);
|
this.tx = new bcoin.txPool(this);
|
||||||
|
|
||||||
this._init();
|
this._init();
|
||||||
@ -132,40 +170,6 @@ Wallet.prototype._init = function init() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.multisig = function multisig(options) {
|
|
||||||
var pub = this.getPublicKey();
|
|
||||||
|
|
||||||
options.type = options.type || options.prefix;
|
|
||||||
options.keys = options.keys || options.pubkeys || [];
|
|
||||||
|
|
||||||
this.type = options.type || 'pubkeyhash';
|
|
||||||
this.keys = [];
|
|
||||||
this.m = options.m || 1;
|
|
||||||
this.n = options.n || 1;
|
|
||||||
this.nmax = this.type === 'scripthash'
|
|
||||||
? (this.compressed ? 15 : 7)
|
|
||||||
: 3;
|
|
||||||
|
|
||||||
this.addKey(pub);
|
|
||||||
|
|
||||||
if (network.prefixes[this.type] == null)
|
|
||||||
throw new Error('Unknown prefix: ' + this.type);
|
|
||||||
|
|
||||||
options.keys.forEach(function(key) {
|
|
||||||
this.addKey(key);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// Use p2sh multisig by default
|
|
||||||
if (!options.type && (this.keys.length > 1 || this.n > 1))
|
|
||||||
this.type = 'scripthash';
|
|
||||||
|
|
||||||
if (this.m < 1 || this.m > this.n)
|
|
||||||
throw new Error('m ranges between 1 and n');
|
|
||||||
|
|
||||||
if (this.n < 1 || this.n > this.nmax)
|
|
||||||
throw new Error('n ranges between 1 and ' + this.nmax);
|
|
||||||
};
|
|
||||||
|
|
||||||
Wallet.prototype.addKey = function addKey(key) {
|
Wallet.prototype.addKey = function addKey(key) {
|
||||||
key = utils.toBuffer(key);
|
key = utils.toBuffer(key);
|
||||||
|
|
||||||
@ -243,16 +247,39 @@ Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getScript = function getScript() {
|
Wallet.prototype.getScript = function getScript() {
|
||||||
|
if (this.type !== 'scripthash')
|
||||||
|
return;
|
||||||
|
|
||||||
if (this.redeem)
|
if (this.redeem)
|
||||||
return this.redeem.slice();
|
return this.redeem.slice();
|
||||||
|
|
||||||
|
if (this.subtype === 'pubkey')
|
||||||
|
return bcoin.script.encode([this.getPublicKey(), 'checksig']);
|
||||||
|
|
||||||
|
if (this.subtype === 'pubkeyhash') {
|
||||||
|
return bcoin.script.encode([
|
||||||
|
'dup',
|
||||||
|
'hash160',
|
||||||
|
this.getKeyHash(),
|
||||||
|
'eqverify',
|
||||||
|
'checksig'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return bcoin.script.encode(bcoin.script.redeem(this.keys, this.m, this.n));
|
return bcoin.script.encode(bcoin.script.redeem(this.keys, this.m, this.n));
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getScriptHash = function getScriptHash() {
|
Wallet.prototype.getScriptHash = function getScriptHash() {
|
||||||
|
if (this.type !== 'scripthash')
|
||||||
|
return;
|
||||||
|
|
||||||
return utils.ripesha(this.getScript());
|
return utils.ripesha(this.getScript());
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getScriptAddress = function getScriptAddress() {
|
Wallet.prototype.getScriptAddress = function getScriptAddress() {
|
||||||
|
if (this.type !== 'scripthash')
|
||||||
|
return;
|
||||||
|
|
||||||
return Wallet.hash2addr(this.getScriptHash(), this.type);
|
return Wallet.hash2addr(this.getScriptHash(), this.type);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -370,8 +397,10 @@ Wallet.prototype.ownOutput = function ownOutput(tx, index) {
|
|||||||
if (bcoin.script.isMultisig(s, keys))
|
if (bcoin.script.isMultisig(s, keys))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (bcoin.script.isScripthash(s, scripthash))
|
if (scripthash) {
|
||||||
return true;
|
if (bcoin.script.isScripthash(s, scripthash))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}, this);
|
}, this);
|
||||||
@ -407,8 +436,10 @@ Wallet.prototype.ownInput = function ownInput(tx, index) {
|
|||||||
// if (bcoin.script.isMultisigInput(input.script, keys, tx, i))
|
// if (bcoin.script.isMultisigInput(input.script, keys, tx, i))
|
||||||
// return true;
|
// return true;
|
||||||
|
|
||||||
if (bcoin.script.isScripthashInput(input.script, redeem))
|
if (redeem) {
|
||||||
return true;
|
if (bcoin.script.isScripthashInput(input.script, redeem))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!input.out.tx)
|
if (!input.out.tx)
|
||||||
return false;
|
return false;
|
||||||
@ -424,8 +455,10 @@ Wallet.prototype.ownInput = function ownInput(tx, index) {
|
|||||||
if (bcoin.script.isMultisig(s, keys))
|
if (bcoin.script.isMultisig(s, keys))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (bcoin.script.isScripthash(s, scripthash))
|
if (scripthash) {
|
||||||
return true;
|
if (bcoin.script.isScripthash(s, scripthash))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}, this);
|
}, this);
|
||||||
@ -589,7 +622,7 @@ Wallet.prototype.toAddress = function toAddress() {
|
|||||||
Wallet.prototype.toJSON = function toJSON(encrypt) {
|
Wallet.prototype.toJSON = function toJSON(encrypt) {
|
||||||
return {
|
return {
|
||||||
v: 2,
|
v: 2,
|
||||||
type: 'wallet',
|
name: 'wallet',
|
||||||
network: network.type,
|
network: network.type,
|
||||||
encrypted: encrypt ? true : false,
|
encrypted: encrypt ? true : false,
|
||||||
label: this.label,
|
label: this.label,
|
||||||
@ -599,16 +632,15 @@ Wallet.prototype.toJSON = function toJSON(encrypt) {
|
|||||||
priv: encrypt
|
priv: encrypt
|
||||||
? encrypt(this.getPrivateKey('base58'))
|
? encrypt(this.getPrivateKey('base58'))
|
||||||
: this.getPrivateKey('base58'),
|
: this.getPrivateKey('base58'),
|
||||||
tx: this.tx.toJSON(),
|
|
||||||
xprivkey: this.hd
|
xprivkey: this.hd
|
||||||
? (encrypt ? encrypt(this.hd.xprivkey) : this.hd.xprivkey)
|
? (encrypt ? encrypt(this.hd.xprivkey) : this.hd.xprivkey)
|
||||||
: null,
|
: null,
|
||||||
multisig: this.n > 1 ? {
|
type: this.type,
|
||||||
type: this.type,
|
subtype: this.subtype,
|
||||||
keys: this.keys.map(utils.toBase58),
|
keys: this.keys.map(utils.toBase58),
|
||||||
m: this.m,
|
m: this.m,
|
||||||
n: this.n
|
n: this.n,
|
||||||
} : undefined
|
tx: this.tx.toJSON()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -616,7 +648,7 @@ Wallet.fromJSON = function fromJSON(json, decrypt) {
|
|||||||
var priv, pub, xprivkey, multisig, compressed, key, w;
|
var priv, pub, xprivkey, multisig, compressed, key, w;
|
||||||
|
|
||||||
assert.equal(json.v, 2);
|
assert.equal(json.v, 2);
|
||||||
assert.equal(json.type, 'wallet');
|
assert.equal(json.name, 'wallet');
|
||||||
|
|
||||||
if (json.network)
|
if (json.network)
|
||||||
assert.equal(json.network, network.type);
|
assert.equal(json.network, network.type);
|
||||||
@ -647,15 +679,6 @@ Wallet.fromJSON = function fromJSON(json, decrypt) {
|
|||||||
compressed = pub[0] !== 0x04;
|
compressed = pub[0] !== 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.multisig) {
|
|
||||||
multisig = {
|
|
||||||
type: json.multisig.type,
|
|
||||||
keys: json.multisig.keys.map(utils.fromBase58),
|
|
||||||
m: json.multisig.m,
|
|
||||||
n: json.multisig.n
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json.xprivkey) {
|
if (json.xprivkey) {
|
||||||
xprivkey = json.xprivkey;
|
xprivkey = json.xprivkey;
|
||||||
if (json.encrypted)
|
if (json.encrypted)
|
||||||
@ -668,7 +691,12 @@ Wallet.fromJSON = function fromJSON(json, decrypt) {
|
|||||||
priv: priv,
|
priv: priv,
|
||||||
pub: pub,
|
pub: pub,
|
||||||
compressed: compressed,
|
compressed: compressed,
|
||||||
multisig: multisig
|
multisig: multisig,
|
||||||
|
type: json.type,
|
||||||
|
subtype: json.subtype,
|
||||||
|
keys: json.keys.map(utils.fromBase58),
|
||||||
|
m: json.m,
|
||||||
|
n: json.n
|
||||||
});
|
});
|
||||||
|
|
||||||
w.tx.fromJSON(json.tx);
|
w.tx.fromJSON(json.tx);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user