remove deprecated functionality
This commit is contained in:
parent
08cc8f8621
commit
8d3686d046
12 changed files with 12 additions and 1301 deletions
29
src/ecdsa.js
29
src/ecdsa.js
|
@ -12,34 +12,7 @@ var ONE = new Buffer([1])
|
|||
function deterministicGenerateK (curve, hash, d, checkSig) {
|
||||
typeForce('Buffer', hash)
|
||||
typeForce('BigInteger', d)
|
||||
|
||||
// FIXME: remove/uncomment for 2.0.0
|
||||
// typeForce('Function', checkSig)
|
||||
|
||||
if (typeof checkSig !== 'function') {
|
||||
console.warn('deterministicGenerateK requires a checkSig callback in 2.0.0, see #337 for more information')
|
||||
|
||||
checkSig = function (k) {
|
||||
var G = curve.G
|
||||
var n = curve.n
|
||||
var e = BigInteger.fromBuffer(hash)
|
||||
|
||||
var Q = G.multiply(k)
|
||||
|
||||
if (curve.isInfinity(Q))
|
||||
return false
|
||||
|
||||
var r = Q.affineX.mod(n)
|
||||
if (r.signum() === 0)
|
||||
return false
|
||||
|
||||
var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n)
|
||||
if (s.signum() === 0)
|
||||
return false
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
typeForce('Function', checkSig)
|
||||
|
||||
// sanity check
|
||||
assert.equal(hash.length, 32, 'Hash must be 256 bit')
|
||||
|
|
|
@ -78,15 +78,7 @@ HDNode.fromSeedHex = function (hex, network) {
|
|||
}
|
||||
|
||||
HDNode.fromBase58 = function (string, network) {
|
||||
return HDNode.fromBuffer(base58check.decode(string), network, true)
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
HDNode.fromBuffer = function (buffer, network, __ignoreDeprecation) {
|
||||
if (!__ignoreDeprecation) {
|
||||
console.warn('HDNode.fromBuffer() is deprecated for removal in 2.x.y, use fromBase58 instead')
|
||||
}
|
||||
|
||||
var buffer = base58check.decode(string)
|
||||
assert.strictEqual(buffer.length, HDNode.LENGTH, 'Invalid buffer length')
|
||||
|
||||
// 4 byte: version bytes
|
||||
|
@ -145,11 +137,6 @@ HDNode.fromBuffer = function (buffer, network, __ignoreDeprecation) {
|
|||
return hd
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
HDNode.fromHex = function (hex, network) {
|
||||
return HDNode.fromBuffer(new Buffer(hex, 'hex'), network)
|
||||
}
|
||||
|
||||
HDNode.prototype.getIdentifier = function () {
|
||||
return bcrypto.hash160(this.pubKey.toBuffer())
|
||||
}
|
||||
|
@ -171,26 +158,11 @@ HDNode.prototype.neutered = function () {
|
|||
return neutered
|
||||
}
|
||||
|
||||
HDNode.prototype.toBase58 = function (isPrivate) {
|
||||
return base58check.encode(this.toBuffer(isPrivate, true))
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
HDNode.prototype.toBuffer = function (isPrivate, __ignoreDeprecation) {
|
||||
if (isPrivate === undefined) {
|
||||
isPrivate = !!this.privKey
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
} else {
|
||||
console.warn('isPrivate flag is deprecated, please use the .neutered() method instead')
|
||||
}
|
||||
|
||||
if (!__ignoreDeprecation) {
|
||||
console.warn('HDNode.toBuffer() is deprecated for removal in 2.x.y, use toBase58 instead')
|
||||
}
|
||||
HDNode.prototype.toBase58 = function (__isPrivate) {
|
||||
assert.strictEqual(__isPrivate, undefined, 'Unsupported argument in 2.0.0')
|
||||
|
||||
// Version
|
||||
var version = isPrivate ? this.network.bip32.private : this.network.bip32.public
|
||||
var version = this.privKey ? this.network.bip32.private : this.network.bip32.public
|
||||
var buffer = new Buffer(HDNode.LENGTH)
|
||||
|
||||
// 4 bytes: version bytes
|
||||
|
@ -210,25 +182,19 @@ HDNode.prototype.toBuffer = function (isPrivate, __ignoreDeprecation) {
|
|||
// 32 bytes: the chain code
|
||||
this.chainCode.copy(buffer, 13)
|
||||
|
||||
// 33 bytes: the public key or private key data
|
||||
if (isPrivate) {
|
||||
// FIXME: remove in 2.x.y
|
||||
assert(this.privKey, 'Missing private key')
|
||||
|
||||
// 33 bytes: the private key, or
|
||||
if (this.privKey) {
|
||||
// 0x00 + k for private keys
|
||||
buffer.writeUInt8(0, 45)
|
||||
this.privKey.d.toBuffer(32).copy(buffer, 46)
|
||||
|
||||
// 33 bytes: the public key
|
||||
} else {
|
||||
// X9.62 encoding for public keys
|
||||
this.pubKey.toBuffer().copy(buffer, 45)
|
||||
}
|
||||
|
||||
return buffer
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
HDNode.prototype.toHex = function (isPrivate) {
|
||||
return this.toBuffer(isPrivate).toString('hex')
|
||||
return base58check.encode(buffer)
|
||||
}
|
||||
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
|
||||
|
|
|
@ -14,6 +14,5 @@ module.exports = {
|
|||
scripts: require('./scripts'),
|
||||
Transaction: require('./transaction'),
|
||||
TransactionBuilder: require('./transaction_builder'),
|
||||
networks: require('./networks'),
|
||||
Wallet: require('./wallet')
|
||||
networks: require('./networks')
|
||||
}
|
||||
|
|
|
@ -291,9 +291,5 @@ module.exports = {
|
|||
pubKeyHashInput: pubKeyHashInput,
|
||||
scriptHashInput: scriptHashInput,
|
||||
multisigInput: multisigInput,
|
||||
dataOutput: function (data) {
|
||||
console.warn('dataOutput is deprecated, use nullDataOutput by 2.0.0')
|
||||
return nullDataOutput(data)
|
||||
},
|
||||
nullDataOutput: nullDataOutput
|
||||
}
|
||||
|
|
|
@ -3,10 +3,8 @@ var bufferutils = require('./bufferutils')
|
|||
var crypto = require('./crypto')
|
||||
var typeForce = require('typeforce')
|
||||
var opcodes = require('./opcodes')
|
||||
var scripts = require('./scripts')
|
||||
|
||||
var Address = require('./address')
|
||||
var ECSignature = require('./ecsignature')
|
||||
var Script = require('./script')
|
||||
|
||||
function Transaction () {
|
||||
|
@ -209,16 +207,6 @@ Transaction.prototype.clone = function () {
|
|||
* used to sign the transaction input in question.
|
||||
*/
|
||||
Transaction.prototype.hashForSignature = function (inIndex, prevOutScript, hashType) {
|
||||
// FIXME: remove in 2.x.y
|
||||
if (arguments[0] instanceof Script) {
|
||||
console.warn('hashForSignature(prevOutScript, inIndex, ...) has been deprecated. Use hashForSignature(inIndex, prevOutScript, ...)')
|
||||
|
||||
// swap the arguments (must be stored in tmp, arguments is special)
|
||||
var tmp = arguments[0]
|
||||
inIndex = arguments[1]
|
||||
prevOutScript = tmp
|
||||
}
|
||||
|
||||
typeForce('Number', inIndex)
|
||||
typeForce('Script', prevOutScript)
|
||||
typeForce('Number', hashType)
|
||||
|
@ -333,37 +321,4 @@ Transaction.prototype.setInputScript = function (index, script) {
|
|||
this.ins[index].script = script
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
Transaction.prototype.sign = function (index, privKey, hashType) {
|
||||
console.warn('Transaction.prototype.sign is deprecated. Use TransactionBuilder instead.')
|
||||
|
||||
var prevOutScript = privKey.pub.getAddress().toOutputScript()
|
||||
var signature = this.signInput(index, prevOutScript, privKey, hashType)
|
||||
|
||||
var scriptSig = scripts.pubKeyHashInput(signature, privKey.pub)
|
||||
this.setInputScript(index, scriptSig)
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
Transaction.prototype.signInput = function (index, prevOutScript, privKey, hashType) {
|
||||
console.warn('Transaction.prototype.signInput is deprecated. Use TransactionBuilder instead.')
|
||||
|
||||
hashType = hashType || Transaction.SIGHASH_ALL
|
||||
|
||||
var hash = this.hashForSignature(index, prevOutScript, hashType)
|
||||
var signature = privKey.sign(hash)
|
||||
|
||||
return signature.toScriptSignature(hashType)
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
Transaction.prototype.validateInput = function (index, prevOutScript, pubKey, buffer) {
|
||||
console.warn('Transaction.prototype.validateInput is deprecated. Use TransactionBuilder instead.')
|
||||
|
||||
var parsed = ECSignature.parseScriptSignature(buffer)
|
||||
var hash = this.hashForSignature(index, prevOutScript, parsed.hashType)
|
||||
|
||||
return pubKey.verify(hash, parsed.signature)
|
||||
}
|
||||
|
||||
module.exports = Transaction
|
||||
|
|
371
src/wallet.js
371
src/wallet.js
|
@ -1,371 +0,0 @@
|
|||
var assert = require('assert')
|
||||
var bufferutils = require('./bufferutils')
|
||||
var crypto = require('crypto')
|
||||
var typeForce = require('typeforce')
|
||||
var networks = require('./networks')
|
||||
|
||||
var Address = require('./address')
|
||||
var HDNode = require('./hdnode')
|
||||
var TransactionBuilder = require('./transaction_builder')
|
||||
var Script = require('./script')
|
||||
|
||||
function Wallet (seed, network) {
|
||||
console.warn('Wallet is deprecated and will be removed in 2.0.0, see #296')
|
||||
|
||||
seed = seed || crypto.randomBytes(32)
|
||||
network = network || networks.bitcoin
|
||||
|
||||
// Stored in a closure to make accidental serialization less likely
|
||||
var masterKey = HDNode.fromSeedBuffer(seed, network)
|
||||
|
||||
// HD first-level child derivation method should be hardened
|
||||
// See https://bitcointalk.org/index.php?topic=405179.msg4415254#msg4415254
|
||||
var accountZero = masterKey.deriveHardened(0)
|
||||
var externalAccount = accountZero.derive(0)
|
||||
var internalAccount = accountZero.derive(1)
|
||||
|
||||
this.addresses = []
|
||||
this.changeAddresses = []
|
||||
this.network = network
|
||||
this.unspents = []
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
this.unspentMap = {}
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
var me = this
|
||||
this.newMasterKey = function (seed) {
|
||||
console.warn('newMasterKey is deprecated, please make a new Wallet instance instead')
|
||||
|
||||
seed = seed || crypto.randomBytes(32)
|
||||
masterKey = HDNode.fromSeedBuffer(seed, network)
|
||||
|
||||
accountZero = masterKey.deriveHardened(0)
|
||||
externalAccount = accountZero.derive(0)
|
||||
internalAccount = accountZero.derive(1)
|
||||
|
||||
me.addresses = []
|
||||
me.changeAddresses = []
|
||||
|
||||
me.unspents = []
|
||||
me.unspentMap = {}
|
||||
}
|
||||
|
||||
this.getMasterKey = function () {
|
||||
return masterKey
|
||||
}
|
||||
this.getAccountZero = function () {
|
||||
return accountZero
|
||||
}
|
||||
this.getExternalAccount = function () {
|
||||
return externalAccount
|
||||
}
|
||||
this.getInternalAccount = function () {
|
||||
return internalAccount
|
||||
}
|
||||
}
|
||||
|
||||
Wallet.prototype.createTransaction = function (to, value, options) {
|
||||
// FIXME: remove in 2.0.0
|
||||
if (typeof options !== 'object') {
|
||||
if (options !== undefined) {
|
||||
console.warn('Non options object parameters are deprecated, use options object instead')
|
||||
|
||||
options = {
|
||||
fixedFee: arguments[2],
|
||||
changeAddress: arguments[3]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options = options || {}
|
||||
|
||||
assert(value > this.network.dustThreshold, value + ' must be above dust threshold (' + this.network.dustThreshold + ' Satoshis)')
|
||||
|
||||
var changeAddress = options.changeAddress
|
||||
var fixedFee = options.fixedFee
|
||||
var minConf = options.minConf === undefined ? 0 : options.minConf // FIXME: change minConf:1 by default in 2.0.0
|
||||
|
||||
// filter by minConf, then pending and sort by descending value
|
||||
var unspents = this.unspents.filter(function (unspent) {
|
||||
return unspent.confirmations >= minConf
|
||||
}).filter(function (unspent) {
|
||||
return !unspent.pending
|
||||
}).sort(function (o1, o2) {
|
||||
return o2.value - o1.value
|
||||
})
|
||||
|
||||
var accum = 0
|
||||
var addresses = []
|
||||
var subTotal = value
|
||||
|
||||
var txb = new TransactionBuilder()
|
||||
txb.addOutput(to, value)
|
||||
|
||||
for (var i = 0; i < unspents.length; ++i) {
|
||||
var unspent = unspents[i]
|
||||
addresses.push(unspent.address)
|
||||
|
||||
txb.addInput(unspent.txHash, unspent.index)
|
||||
|
||||
var fee = fixedFee === undefined ? estimatePaddedFee(txb.buildIncomplete(), this.network) : fixedFee
|
||||
|
||||
accum += unspent.value
|
||||
subTotal = value + fee
|
||||
|
||||
if (accum >= subTotal) {
|
||||
var change = accum - subTotal
|
||||
|
||||
if (change > this.network.dustThreshold) {
|
||||
txb.addOutput(changeAddress || this.getChangeAddress(), change)
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
assert(accum >= subTotal, 'Not enough funds (incl. fee): ' + accum + ' < ' + subTotal)
|
||||
|
||||
return this.signWith(txb, addresses).build()
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
Wallet.prototype.processPendingTx = function (tx) {
|
||||
this.__processTx(tx, true)
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
Wallet.prototype.processConfirmedTx = function (tx) {
|
||||
this.__processTx(tx, false)
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
Wallet.prototype.__processTx = function (tx, isPending) {
|
||||
console.warn('processTransaction is considered harmful, see issue #260 for more information')
|
||||
|
||||
var txId = tx.getId()
|
||||
var txHash = tx.getHash()
|
||||
|
||||
tx.outs.forEach(function (txOut, i) {
|
||||
var address
|
||||
|
||||
try {
|
||||
address = Address.fromOutputScript(txOut.script, this.network).toString()
|
||||
} catch (e) {
|
||||
if (!(e.message.match(/has no matching Address/)))
|
||||
throw e
|
||||
}
|
||||
|
||||
var myAddresses = this.addresses.concat(this.changeAddresses)
|
||||
if (myAddresses.indexOf(address) > -1) {
|
||||
var lookup = txId + ':' + i
|
||||
if (lookup in this.unspentMap) return
|
||||
|
||||
// its unique, add it
|
||||
var unspent = {
|
||||
address: address,
|
||||
confirmations: 0, // no way to determine this without more information
|
||||
index: i,
|
||||
txHash: txHash,
|
||||
txId: txId,
|
||||
value: txOut.value,
|
||||
pending: isPending
|
||||
}
|
||||
|
||||
this.unspentMap[lookup] = unspent
|
||||
this.unspents.push(unspent)
|
||||
}
|
||||
}, this)
|
||||
|
||||
tx.ins.forEach(function (txIn) {
|
||||
// copy and convert to big-endian hex
|
||||
var txInId = bufferutils.reverse(txIn.hash).toString('hex')
|
||||
|
||||
var lookup = txInId + ':' + txIn.index
|
||||
if (!(lookup in this.unspentMap)) return
|
||||
|
||||
var unspent = this.unspentMap[lookup]
|
||||
|
||||
if (isPending) {
|
||||
unspent.pending = true
|
||||
unspent.spent = true
|
||||
} else {
|
||||
delete this.unspentMap[lookup]
|
||||
|
||||
this.unspents = this.unspents.filter(function (unspent2) {
|
||||
return unspent !== unspent2
|
||||
})
|
||||
}
|
||||
}, this)
|
||||
}
|
||||
|
||||
Wallet.prototype.generateAddress = function () {
|
||||
var k = this.addresses.length
|
||||
var address = this.getExternalAccount().derive(k).getAddress()
|
||||
|
||||
this.addresses.push(address.toString())
|
||||
|
||||
return this.getReceiveAddress()
|
||||
}
|
||||
|
||||
Wallet.prototype.generateChangeAddress = function () {
|
||||
var k = this.changeAddresses.length
|
||||
var address = this.getInternalAccount().derive(k).getAddress()
|
||||
|
||||
this.changeAddresses.push(address.toString())
|
||||
|
||||
return this.getChangeAddress()
|
||||
}
|
||||
|
||||
Wallet.prototype.getAddress = function () {
|
||||
if (this.addresses.length === 0) {
|
||||
this.generateAddress()
|
||||
}
|
||||
|
||||
return this.addresses[this.addresses.length - 1]
|
||||
}
|
||||
|
||||
Wallet.prototype.getBalance = function (minConf) {
|
||||
minConf = minConf || 0
|
||||
|
||||
return this.unspents.filter(function (unspent) {
|
||||
return unspent.confirmations >= minConf
|
||||
|
||||
// FIXME: remove spent filter in 2.0.0
|
||||
}).filter(function (unspent) {
|
||||
return !unspent.spent
|
||||
}).reduce(function (accum, unspent) {
|
||||
return accum + unspent.value
|
||||
}, 0)
|
||||
}
|
||||
|
||||
Wallet.prototype.getChangeAddress = function () {
|
||||
if (this.changeAddresses.length === 0) {
|
||||
this.generateChangeAddress()
|
||||
}
|
||||
|
||||
return this.changeAddresses[this.changeAddresses.length - 1]
|
||||
}
|
||||
|
||||
Wallet.prototype.getInternalPrivateKey = function (index) {
|
||||
return this.getInternalAccount().derive(index).privKey
|
||||
}
|
||||
|
||||
Wallet.prototype.getPrivateKey = function (index) {
|
||||
return this.getExternalAccount().derive(index).privKey
|
||||
}
|
||||
|
||||
Wallet.prototype.getPrivateKeyForAddress = function (address) {
|
||||
var index
|
||||
|
||||
if ((index = this.addresses.indexOf(address)) > -1) {
|
||||
return this.getPrivateKey(index)
|
||||
}
|
||||
|
||||
if ((index = this.changeAddresses.indexOf(address)) > -1) {
|
||||
return this.getInternalPrivateKey(index)
|
||||
}
|
||||
|
||||
assert(false, 'Unknown address. Make sure the address is from the keychain and has been generated')
|
||||
}
|
||||
|
||||
Wallet.prototype.getUnspentOutputs = function (minConf) {
|
||||
minConf = minConf || 0
|
||||
|
||||
return this.unspents.filter(function (unspent) {
|
||||
return unspent.confirmations >= minConf
|
||||
|
||||
// FIXME: remove spent filter in 2.0.0
|
||||
}).filter(function (unspent) {
|
||||
return !unspent.spent
|
||||
}).map(function (unspent) {
|
||||
return {
|
||||
address: unspent.address,
|
||||
confirmations: unspent.confirmations,
|
||||
index: unspent.index,
|
||||
txId: unspent.txId,
|
||||
value: unspent.value,
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
hash: unspent.txId,
|
||||
pending: unspent.pending
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Wallet.prototype.setUnspentOutputs = function (unspents) {
|
||||
this.unspentMap = {}
|
||||
this.unspents = unspents.map(function (unspent) {
|
||||
// FIXME: remove unspent.hash in 2.0.0
|
||||
var txId = unspent.txId || unspent.hash
|
||||
var index = unspent.index
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
if (unspent.hash !== undefined) {
|
||||
console.warn('unspent.hash is deprecated, use unspent.txId instead')
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
if (index === undefined) {
|
||||
console.warn('unspent.outputIndex is deprecated, use unspent.index instead')
|
||||
index = unspent.outputIndex
|
||||
}
|
||||
|
||||
typeForce('String', txId)
|
||||
typeForce('Number', index)
|
||||
typeForce('Number', unspent.value)
|
||||
|
||||
assert.equal(txId.length, 64, 'Expected valid txId, got ' + txId)
|
||||
assert.doesNotThrow(function () {
|
||||
Address.fromBase58Check(unspent.address)
|
||||
}, 'Expected Base58 Address, got ' + unspent.address)
|
||||
assert(isFinite(index), 'Expected finite index, got ' + index)
|
||||
|
||||
// FIXME: remove branch in 2.0.0
|
||||
if (unspent.confirmations !== undefined) {
|
||||
typeForce('Number', unspent.confirmations)
|
||||
}
|
||||
|
||||
var txHash = bufferutils.reverse(new Buffer(txId, 'hex'))
|
||||
|
||||
unspent = {
|
||||
address: unspent.address,
|
||||
confirmations: unspent.confirmations || 0,
|
||||
index: index,
|
||||
txHash: txHash,
|
||||
txId: txId,
|
||||
value: unspent.value,
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
pending: unspent.pending || false
|
||||
}
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
this.unspentMap[txId + ':' + index] = unspent
|
||||
|
||||
return unspent
|
||||
}, this)
|
||||
}
|
||||
|
||||
Wallet.prototype.signWith = function (tx, addresses) {
|
||||
addresses.forEach(function (address, i) {
|
||||
var privKey = this.getPrivateKeyForAddress(address)
|
||||
|
||||
tx.sign(i, privKey)
|
||||
}, this)
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
function estimatePaddedFee (tx, network) {
|
||||
var tmpTx = tx.clone()
|
||||
tmpTx.addOutput(Script.EMPTY, network.dustSoftThreshold || 0)
|
||||
|
||||
return network.estimateFee(tmpTx)
|
||||
}
|
||||
|
||||
// FIXME: 1.0.0 shims, remove in 2.0.0
|
||||
Wallet.prototype.getReceiveAddress = Wallet.prototype.getAddress
|
||||
Wallet.prototype.createTx = Wallet.prototype.createTransaction
|
||||
|
||||
module.exports = Wallet
|
Loading…
Add table
Add a link
Reference in a new issue