script and standard transaction types. prefixes.
This commit is contained in:
parent
07a6788831
commit
3e608c2cc6
@ -545,7 +545,7 @@ Pool.prototype.removeWallet = function removeWallet(w) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype.watchWallet = function watchWallet(w) {
|
Pool.prototype.watchWallet = function watchWallet(w) {
|
||||||
if (w.type === 'script') {
|
if (w.type === 'scripthash') {
|
||||||
// For the redeem script hash in outputs:
|
// For the redeem script hash in outputs:
|
||||||
this.watch(w.getFullHash());
|
this.watch(w.getFullHash());
|
||||||
// For the redeem script in inputs:
|
// For the redeem script in inputs:
|
||||||
@ -558,7 +558,7 @@ Pool.prototype.watchWallet = function watchWallet(w) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype.unwatchWallet = function unwatchWallet(w) {
|
Pool.prototype.unwatchWallet = function unwatchWallet(w) {
|
||||||
if (w.type === 'script') {
|
if (w.type === 'scripthash') {
|
||||||
// For the redeem script hash in p2sh outputs:
|
// For the redeem script hash in p2sh outputs:
|
||||||
this.unwatch(w.getFullHash());
|
this.unwatch(w.getFullHash());
|
||||||
// For the redeem script in p2sh inputs:
|
// For the redeem script in p2sh inputs:
|
||||||
|
|||||||
@ -20,7 +20,9 @@ var main = network.main = {};
|
|||||||
|
|
||||||
main.prefixes = {
|
main.prefixes = {
|
||||||
pubkey: 0,
|
pubkey: 0,
|
||||||
script: 5,
|
pubkeyhash: 0,
|
||||||
|
multisig: 0,
|
||||||
|
scripthash: 5,
|
||||||
privkey: 128,
|
privkey: 128,
|
||||||
xpubkey: 0x0488b21e,
|
xpubkey: 0x0488b21e,
|
||||||
xprivkey: 0x0488ade4
|
xprivkey: 0x0488ade4
|
||||||
@ -107,7 +109,9 @@ testnet.type = 'testnet';
|
|||||||
|
|
||||||
testnet.prefixes = {
|
testnet.prefixes = {
|
||||||
pubkey: 111,
|
pubkey: 111,
|
||||||
script: 196,
|
pubkeyhash: 111,
|
||||||
|
multisig: 111,
|
||||||
|
scripthash: 196,
|
||||||
privkey: 239,
|
privkey: 239,
|
||||||
xpubkey: 0x043587cf,
|
xpubkey: 0x043587cf,
|
||||||
xprivkey: 0x04358394
|
xprivkey: 0x04358394
|
||||||
|
|||||||
@ -783,7 +783,27 @@ script.multisig = function(keys, m, n) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script.standard = function standard(s) {
|
||||||
|
return (script.isPubkey(s) && 'pubkey')
|
||||||
|
|| (script.isPubkeyhash(s) && 'pubkeyhash')
|
||||||
|
|| (script.isMultisig(s) && 'multisig')
|
||||||
|
|| (script.isScripthash(s) && 'scripthash')
|
||||||
|
|| (script.isNullData(s) && 'colored')
|
||||||
|
|| 'nonstandard';
|
||||||
|
};
|
||||||
|
|
||||||
|
script.lockTime = function lockTime(s) {
|
||||||
|
return s.length > 3
|
||||||
|
&& Array.isArray(s[0])
|
||||||
|
&& s[1] === 'checklocktimeverify'
|
||||||
|
&& s[2] === 'drop'
|
||||||
|
&& new bn(s[0]);
|
||||||
|
};
|
||||||
|
|
||||||
script.isPubkeyhash = function isPubkeyhash(s, hash) {
|
script.isPubkeyhash = function isPubkeyhash(s, hash) {
|
||||||
|
if (script.lockTime(s))
|
||||||
|
s = s.slice(3);
|
||||||
|
|
||||||
if (s.length !== 5)
|
if (s.length !== 5)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -801,7 +821,10 @@ script.isPubkeyhash = function isPubkeyhash(s, hash) {
|
|||||||
return s[2];
|
return s[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
script.isSimplePubkeyhash = function isSimplePubkeyhash(s, hash) {
|
script.isPubkey = function isPubkey(s, hash) {
|
||||||
|
if (script.lockTime(s))
|
||||||
|
s = s.slice(3);
|
||||||
|
|
||||||
if (s.length !== 2)
|
if (s.length !== 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -816,6 +839,9 @@ script.isSimplePubkeyhash = function isSimplePubkeyhash(s, hash) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
script.isMultisig = function isMultisig(s, key) {
|
script.isMultisig = function isMultisig(s, key) {
|
||||||
|
if (script.lockTime(s))
|
||||||
|
s = s.slice(3);
|
||||||
|
|
||||||
if (s.length < 4)
|
if (s.length < 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -863,6 +889,9 @@ script.isPubkeyhashInput = function isPubkeyhashInput(s) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
script.isScripthash = function isScripthash(s, hash) {
|
script.isScripthash = function isScripthash(s, hash) {
|
||||||
|
if (script.lockTime(s))
|
||||||
|
s = s.slice(3);
|
||||||
|
|
||||||
if (s.length !== 3)
|
if (s.length !== 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@ -156,8 +156,15 @@ TX.prototype.scriptInput = function(input, pub) {
|
|||||||
if (input.script.length)
|
if (input.script.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// P2PKH and simple tx
|
// P2PK
|
||||||
if (bcoin.script.isPubkeyhash(s) || bcoin.script.isSimplePubkeyhash(s)) {
|
if (bcoin.script.isPubkey(s)) {
|
||||||
|
input.script = [ [] ];
|
||||||
|
this._recalculateFee();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// P2PKH
|
||||||
|
if (bcoin.script.isPubkeyhash(s)) {
|
||||||
input.script = [ [], pub ];
|
input.script = [ [], pub ];
|
||||||
this._recalculateFee();
|
this._recalculateFee();
|
||||||
return;
|
return;
|
||||||
@ -220,8 +227,14 @@ TX.prototype.signInput = function(input, key, type) {
|
|||||||
// Add the sighash as a single byte to the signature
|
// Add the sighash as a single byte to the signature
|
||||||
signature = signature.concat(type);
|
signature = signature.concat(type);
|
||||||
|
|
||||||
// P2PKH and simple tx
|
// P2PK
|
||||||
if (bcoin.script.isPubkeyhash(s) || bcoin.script.isSimplePubkeyhash(s)) {
|
if (bcoin.script.isPubkey(s)) {
|
||||||
|
input.script[0] = signature;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// P2PKH
|
||||||
|
if (bcoin.script.isPubkeyhash(s)) {
|
||||||
input.script[0] = signature;
|
input.script[0] = signature;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -345,7 +358,7 @@ TX.prototype.scriptOutput = function(output, options) {
|
|||||||
|
|
||||||
if (keys === options.address) {
|
if (keys === options.address) {
|
||||||
keys = keys.map(function(address) {
|
keys = keys.map(function(address) {
|
||||||
return bcoin.wallet.addr2hash(address, 'pubkey');
|
return bcoin.wallet.addr2hash(address, 'pubkeyhash');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,13 +380,13 @@ TX.prototype.scriptOutput = function(output, options) {
|
|||||||
assert(n >= 1 && n <= 3);
|
assert(n >= 1 && n <= 3);
|
||||||
|
|
||||||
script = bcoin.script.multisig(keys, m, n);
|
script = bcoin.script.multisig(keys, m, n);
|
||||||
} else if (bcoin.wallet.validateAddress(options.address, 'script')) {
|
} else if (bcoin.wallet.validateAddress(options.address, 'scripthash')) {
|
||||||
// p2sh transaction
|
// p2sh transaction
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
|
// https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
|
||||||
// hash160 [20-byte-redeemscript-hash] equal
|
// hash160 [20-byte-redeemscript-hash] equal
|
||||||
script = [
|
script = [
|
||||||
'hash160',
|
'hash160',
|
||||||
bcoin.wallet.addr2hash(options.address, 'script'),
|
bcoin.wallet.addr2hash(options.address, 'scripthash'),
|
||||||
'eq'
|
'eq'
|
||||||
];
|
];
|
||||||
} else if (options.address) {
|
} else if (options.address) {
|
||||||
@ -382,7 +395,7 @@ TX.prototype.scriptOutput = function(output, options) {
|
|||||||
script = [
|
script = [
|
||||||
'dup',
|
'dup',
|
||||||
'hash160',
|
'hash160',
|
||||||
bcoin.wallet.addr2hash(options.address, 'pubkey'),
|
bcoin.wallet.addr2hash(options.address, 'pubkeyhash'),
|
||||||
'eqverify',
|
'eqverify',
|
||||||
'checksig'
|
'checksig'
|
||||||
];
|
];
|
||||||
@ -543,7 +556,13 @@ TX.prototype.maxSize = function maxSize() {
|
|||||||
// Get the previous output's subscript
|
// Get the previous output's subscript
|
||||||
var s = input.out.tx.getSubscript(input.out.index);
|
var s = input.out.tx.getSubscript(input.out.index);
|
||||||
|
|
||||||
if (bcoin.script.isPubkeyhash(s) || bcoin.script.isSimplePubkeyhash(s)) {
|
if (bcoin.script.isPubkey(s)) {
|
||||||
|
// Signature + len
|
||||||
|
size += 74;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bcoin.script.isPubkeyhash(s)) {
|
||||||
// Signature + len
|
// Signature + len
|
||||||
size += 74;
|
size += 74;
|
||||||
// Pub key + len
|
// Pub key + len
|
||||||
@ -760,7 +779,7 @@ TX.prototype.inputAddrs = function inputAddrs() {
|
|||||||
}).map(function(input) {
|
}).map(function(input) {
|
||||||
var pub = input.script[1];
|
var pub = input.script[1];
|
||||||
var hash = utils.ripesha(pub);
|
var hash = utils.ripesha(pub);
|
||||||
return bcoin.wallet.hash2addr(hash, 'pubkey');
|
return bcoin.wallet.hash2addr(hash, 'pubkeyhash');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -790,7 +809,7 @@ TX.getInputKey = function(input) {
|
|||||||
if (bcoin.script.isScripthash(script)) {
|
if (bcoin.script.isScripthash(script)) {
|
||||||
var pub = script[script.length - 1];
|
var pub = script[script.length - 1];
|
||||||
var hash = utils.ripesha(pub);
|
var hash = utils.ripesha(pub);
|
||||||
var addr = bcoin.wallet.hash2addr(hash, 'script');
|
var addr = bcoin.wallet.hash2addr(hash, 'scripthash');
|
||||||
var redeem = bcoin.script.decode(pub);
|
var redeem = bcoin.script.decode(pub);
|
||||||
var keys = TX.getOutputKey({ script: redeem });
|
var keys = TX.getOutputKey({ script: redeem });
|
||||||
keys.pub = pub;
|
keys.pub = pub;
|
||||||
@ -814,18 +833,7 @@ TX.getOutputKey = function(output) {
|
|||||||
|
|
||||||
var script = output.script;
|
var script = output.script;
|
||||||
|
|
||||||
if (bcoin.script.isPubkeyhash(script)) {
|
if (bcoin.script.isPubkey(script)) {
|
||||||
var hash = script[2];
|
|
||||||
var addr = bcoin.wallet.hash2addr(hash);
|
|
||||||
return {
|
|
||||||
sig: null,
|
|
||||||
pub: null,
|
|
||||||
hash: hash,
|
|
||||||
addr: addr
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bcoin.script.isSimplePubkeyhash(script)) {
|
|
||||||
var pubKey = script[0];
|
var pubKey = script[0];
|
||||||
var hash = utils.ripesha(pubKey);
|
var hash = utils.ripesha(pubKey);
|
||||||
var addr = bcoin.wallet.hash2addr(hash);
|
var addr = bcoin.wallet.hash2addr(hash);
|
||||||
@ -837,6 +845,17 @@ TX.getOutputKey = function(output) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bcoin.script.isPubkeyhash(script)) {
|
||||||
|
var hash = script[2];
|
||||||
|
var addr = bcoin.wallet.hash2addr(hash);
|
||||||
|
return {
|
||||||
|
sig: null,
|
||||||
|
pub: null,
|
||||||
|
hash: hash,
|
||||||
|
addr: addr
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var pubKeys = bcoin.script.isMultisig(script);
|
var pubKeys = bcoin.script.isMultisig(script);
|
||||||
if (pubKeys) {
|
if (pubKeys) {
|
||||||
var keys = pubKeys.map(function(pubKey) {
|
var keys = pubKeys.map(function(pubKey) {
|
||||||
@ -859,7 +878,7 @@ TX.getOutputKey = function(output) {
|
|||||||
|
|
||||||
if (bcoin.script.isScripthash(script, scriptHash)) {
|
if (bcoin.script.isScripthash(script, scriptHash)) {
|
||||||
var hash = utils.toHex(s[1]);
|
var hash = utils.toHex(s[1]);
|
||||||
var addr = bcoin.wallet.hash2addr(hash, 'script');
|
var addr = bcoin.wallet.hash2addr(hash, 'scripthash');
|
||||||
return {
|
return {
|
||||||
sig: null,
|
sig: null,
|
||||||
pub: null,
|
pub: null,
|
||||||
|
|||||||
@ -66,7 +66,7 @@ function Wallet(options, passphrase) {
|
|||||||
this.key = bcoin.ecdsa.genKeyPair();
|
this.key = bcoin.ecdsa.genKeyPair();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.type = 'pubkey';
|
this.type = 'pubkeyhash';
|
||||||
this.keys = [];
|
this.keys = [];
|
||||||
this.m = 1;
|
this.m = 1;
|
||||||
this.n = 1;
|
this.n = 1;
|
||||||
@ -123,12 +123,12 @@ Wallet.prototype.multisig = function multisig(options) {
|
|||||||
options.type = options.type || options.prefix;
|
options.type = options.type || options.prefix;
|
||||||
options.keys = options.keys || options.pubkeys || [];
|
options.keys = options.keys || options.pubkeys || [];
|
||||||
|
|
||||||
this.type = options.type || 'pubkey';
|
this.type = options.type || 'pubkeyhash';
|
||||||
// this.keys = (options.keys || []).map(utils.toKeyArray);
|
// this.keys = (options.keys || []).map(utils.toKeyArray);
|
||||||
this.keys = [];
|
this.keys = [];
|
||||||
this.m = options.m || 1;
|
this.m = options.m || 1;
|
||||||
this.n = options.n || 1;
|
this.n = options.n || 1;
|
||||||
this.nmax = this.type === 'script'
|
this.nmax = this.type === 'scripthash'
|
||||||
? (this.compressed ? 15 : 7)
|
? (this.compressed ? 15 : 7)
|
||||||
: 3;
|
: 3;
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ Wallet.prototype.multisig = function multisig(options) {
|
|||||||
|
|
||||||
// Use p2sh multisig by default
|
// Use p2sh multisig by default
|
||||||
if (!options.type && this.keys.length > 1)
|
if (!options.type && this.keys.length > 1)
|
||||||
this.type = 'script';
|
this.type = 'scripthash';
|
||||||
|
|
||||||
if (this.m < 1 || this.m > this.n)
|
if (this.m < 1 || this.m > this.n)
|
||||||
throw new Error('m ranges between 1 and n');
|
throw new Error('m ranges between 1 and n');
|
||||||
@ -236,7 +236,7 @@ Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
|
|||||||
Wallet.prototype.getFullPublicKey = function getFullPublicKey(enc) {
|
Wallet.prototype.getFullPublicKey = function getFullPublicKey(enc) {
|
||||||
var pub = this.getOwnPublicKey();
|
var pub = this.getOwnPublicKey();
|
||||||
|
|
||||||
if (this.type === 'script') {
|
if (this.type === 'scripthash') {
|
||||||
var keys = this.getPublicKeys();
|
var keys = this.getPublicKeys();
|
||||||
pub = bcoin.script.encode(bcoin.script.multisig(keys, this.m, this.n));
|
pub = bcoin.script.encode(bcoin.script.multisig(keys, this.m, this.n));
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ Wallet.key2hash = function key2hash(key) {
|
|||||||
Wallet.hash2addr = function hash2addr(hash, prefix) {
|
Wallet.hash2addr = function hash2addr(hash, prefix) {
|
||||||
hash = utils.toArray(hash, 'hex');
|
hash = utils.toArray(hash, 'hex');
|
||||||
|
|
||||||
prefix = network.prefixes[prefix || 'pubkey'];
|
prefix = network.prefixes[prefix || 'pubkeyhash'];
|
||||||
hash = [ prefix ].concat(hash);
|
hash = [ prefix ].concat(hash);
|
||||||
|
|
||||||
var addr = hash.concat(utils.checksum(hash));
|
var addr = hash.concat(utils.checksum(hash));
|
||||||
@ -317,7 +317,7 @@ Wallet.hash2addr = function hash2addr(hash, prefix) {
|
|||||||
|
|
||||||
Wallet.__defineGetter__('prefixes', function() {
|
Wallet.__defineGetter__('prefixes', function() {
|
||||||
if (Wallet._prefixes) return Wallet._prefixes;
|
if (Wallet._prefixes) return Wallet._prefixes;
|
||||||
Wallet._prefixes = ['pubkey', 'script'].reduce(function(out, prefix) {
|
Wallet._prefixes = ['pubkeyhash', 'scripthash'].reduce(function(out, prefix) {
|
||||||
var ch = Wallet.hash2addr(Wallet.key2hash([]), prefix)[0];
|
var ch = Wallet.hash2addr(Wallet.key2hash([]), prefix)[0];
|
||||||
out[ch] = prefix;
|
out[ch] = prefix;
|
||||||
return out;
|
return out;
|
||||||
@ -332,7 +332,7 @@ Wallet.addr2hash = function addr2hash(addr, prefix) {
|
|||||||
if (!Array.isArray(addr))
|
if (!Array.isArray(addr))
|
||||||
addr = utils.fromBase58(addr);
|
addr = utils.fromBase58(addr);
|
||||||
|
|
||||||
prefix = network.prefixes[prefix || 'pubkey'];
|
prefix = network.prefixes[prefix || 'pubkeyhash'];
|
||||||
|
|
||||||
if (addr.length !== 25)
|
if (addr.length !== 25)
|
||||||
return [];
|
return [];
|
||||||
@ -365,10 +365,10 @@ Wallet.prototype.ownOutput = function ownOutput(tx, index) {
|
|||||||
|
|
||||||
var s = output.script;
|
var s = output.script;
|
||||||
|
|
||||||
if (bcoin.script.isPubkeyhash(s, hash))
|
if (bcoin.script.isPubkey(s, hash))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (bcoin.script.isSimplePubkeyhash(s, hash))
|
if (bcoin.script.isPubkeyhash(s, hash))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (bcoin.script.isMultisig(s, key))
|
if (bcoin.script.isMultisig(s, key))
|
||||||
|
|||||||
@ -280,7 +280,7 @@ describe('Wallet', function() {
|
|||||||
var w1 = bcoin.wallet({
|
var w1 = bcoin.wallet({
|
||||||
key: key1,
|
key: key1,
|
||||||
multisig: {
|
multisig: {
|
||||||
type: 'script',
|
type: 'scripthash',
|
||||||
keys: [pub2, pub3],
|
keys: [pub2, pub3],
|
||||||
m: 2,
|
m: 2,
|
||||||
n: 3
|
n: 3
|
||||||
@ -289,7 +289,7 @@ describe('Wallet', function() {
|
|||||||
var w2 = bcoin.wallet({
|
var w2 = bcoin.wallet({
|
||||||
key: key2,
|
key: key2,
|
||||||
multisig: {
|
multisig: {
|
||||||
type: 'script',
|
type: 'scripthash',
|
||||||
keys: [pub1, pub3],
|
keys: [pub1, pub3],
|
||||||
m: 2,
|
m: 2,
|
||||||
n: 3
|
n: 3
|
||||||
@ -298,7 +298,7 @@ describe('Wallet', function() {
|
|||||||
var w3 = bcoin.wallet({
|
var w3 = bcoin.wallet({
|
||||||
key: key3,
|
key: key3,
|
||||||
multisig: {
|
multisig: {
|
||||||
type: 'script',
|
type: 'scripthash',
|
||||||
keys: [pub1, pub2],
|
keys: [pub1, pub2],
|
||||||
m: 2,
|
m: 2,
|
||||||
n: 3
|
n: 3
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user