Added some transaction methods, and removed all internal use of base64
This commit is contained in:
parent
9922864da4
commit
e43d23235b
10 changed files with 107 additions and 41 deletions
6
bitcoinjs-min.js
vendored
6
bitcoinjs-min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -35,8 +35,8 @@ Address.prototype.toString = function () {
|
|||
return base58.checkEncode(hash,this.version);
|
||||
};
|
||||
|
||||
Address.prototype.getHashBase64 = function () {
|
||||
return conv.bytesToBase64(this.hash);
|
||||
Address.prototype.getHash = function () {
|
||||
return conv.bytesToHex(this.hash);
|
||||
};
|
||||
|
||||
Address.getVersion = function(string) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// https://en.bitcoin.it/wiki/Base58Check_encoding
|
||||
|
||||
var BigInteger = require('./jsbn/jsbn');
|
||||
var Crypto = require('./crypto-js/crypto');
|
||||
|
||||
var alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
var base = BigInteger.valueOf(58);
|
||||
|
@ -36,6 +37,10 @@ module.exports.encode = function (input) {
|
|||
return chars.reverse().join('');
|
||||
},
|
||||
|
||||
module.exports.encodeHex = function (input) {
|
||||
return Crypto.util.bytesToHex(module.exports.encode(input));
|
||||
}
|
||||
|
||||
// decode a base58 string into a byte array
|
||||
// input should be a base58 encoded string
|
||||
// @return Array
|
||||
|
@ -76,16 +81,24 @@ module.exports.decode = function (input) {
|
|||
return bytes;
|
||||
}
|
||||
|
||||
module.exports.checkEncode = function(x,vbyte,format) {
|
||||
module.exports.decodeHex = function (input) {
|
||||
return module.exports.decode(Crypto.util.hexToBytes(input));
|
||||
}
|
||||
|
||||
module.exports.checkEncode = function(input, vbyte) {
|
||||
vbyte = vbyte || 0;
|
||||
var front = [vbyte].concat(x);
|
||||
var front = [vbyte].concat(input);
|
||||
var checksum = Crypto.SHA256(Crypto.SHA256(front, {asBytes: true}), {asBytes: true})
|
||||
.slice(0,4);
|
||||
return module.exports.encode(front.concat(checksum));
|
||||
}
|
||||
|
||||
module.exports.checkDecode = function(x) {
|
||||
var bytes = module.exports.decode(x),
|
||||
module.exports.checkEncodeHex = function (input, vbyte) {
|
||||
return Crypto.util.bytesToHex(module.exports.encode(input));
|
||||
}
|
||||
|
||||
module.exports.checkDecode = function(input) {
|
||||
var bytes = module.exports.decode(input),
|
||||
front = bytes.slice(0,bytes.length-4),
|
||||
back = bytes.slice(bytes.length-4);
|
||||
var checksum = Crypto.SHA256(Crypto.SHA256(front,{asBytes: true}), {asBytes: true})
|
||||
|
@ -98,4 +111,8 @@ module.exports.checkDecode = function(x) {
|
|||
return o;
|
||||
}
|
||||
|
||||
module.exports.checkDecodeHex = function (input) {
|
||||
return module.exports.checkDecode(Crypto.util.hexToBytes(input));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
buffer = buffer.concat(numToVarInt(tx.ins.length));
|
||||
for (var i = 0; i < tx.ins.length; i++) {
|
||||
var txin = tx.ins[i];
|
||||
buffer = buffer.concat(Crypto.util.base64ToBytes(txin.outpoint.hash));
|
||||
buffer = buffer.concat(Crypto.util.hexToBytes(txin.outpoint.hash));
|
||||
buffer = buffer.concat(Crypto.util.wordsToBytes([parseInt(txin.index)]));
|
||||
var scriptBytes = Crypto.util.base64ToBytes(txin.script);
|
||||
var scriptBytes = Crypto.util.hexToBytes(txin.script);
|
||||
buffer = buffer.concat(numToVarInt(scriptBytes.length));
|
||||
buffer = buffer.concat(scriptBytes);
|
||||
buffer = buffer.concat(Crypto.util.wordsToBytes([parseInt(txin.sequence)]));
|
||||
|
@ -35,7 +35,7 @@
|
|||
var valueHex = (new BigInteger(txout.value, 10)).toString(16);
|
||||
while (valueHex.length < 16) valueHex = "0" + valueHex;
|
||||
buffer = buffer.concat(Crypto.util.hexToBytes(valueHex));
|
||||
var scriptBytes = Crypto.util.base64ToBytes(txout.script);
|
||||
var scriptBytes = Crypto.util.hexToBytes(txout.script);
|
||||
buffer = buffer.concat(numToVarInt(scriptBytes.length));
|
||||
buffer = buffer.concat(scriptBytes);
|
||||
}
|
||||
|
@ -64,9 +64,9 @@
|
|||
|
||||
// Blank out other inputs' signatures
|
||||
for (var i = 0; i < txTmp.ins.length; i++) {
|
||||
txTmp.ins[i].script = Crypto.util.bytesToBase64([]);
|
||||
txTmp.ins[i].script = Crypto.util.bytesToHex([]);
|
||||
}
|
||||
txTmp.ins[inIndex].script = Crypto.util.bytesToBase64(scriptCode);
|
||||
txTmp.ins[inIndex].script = Crypto.util.bytesToHex(scriptCode);
|
||||
|
||||
// Blank out some of the outputs
|
||||
if ((hashType & 0x1f) == SIGHASH_NONE) {
|
||||
|
|
10
src/eckey.js
10
src/eckey.js
|
@ -40,11 +40,13 @@ var ECKey = function (input) {
|
|||
this.compressed = true;
|
||||
} else {
|
||||
// hex string?
|
||||
// //wtf is base64 here for?
|
||||
// Prepend zero byte to prevent interpretation as negative integer
|
||||
this.priv = BigInteger.fromByteArrayUnsigned(conv.base64ToBytes(input));
|
||||
this.priv = BigInteger.fromByteArrayUnsigned(Crypto.util.hexToBytes(input));
|
||||
}
|
||||
}
|
||||
else if (input.constructor == [].constructor) {
|
||||
this.priv = BigInteger.fromByteArrayUnsigned(input);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(shtylman) methods
|
||||
|
@ -116,8 +118,8 @@ ECKey.prototype.setPub = function (pub) {
|
|||
};
|
||||
|
||||
ECKey.prototype.toString = function (format) {
|
||||
if (format === "base64") {
|
||||
return conv.bytesToBase64(this.priv.toByteArrayUnsigned());
|
||||
if (format === "base58") {
|
||||
return base58.checkEncode(this.priv.toByteArrayUnsigned(),128);
|
||||
} else {
|
||||
return Crypto.util.bytesToHex(this.priv.toByteArrayUnsigned());
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ module.exports = {
|
|||
Key: require('./eckey'),
|
||||
Message: require('./message'),
|
||||
BigInteger: require('./jsbn/jsbn'),
|
||||
Crypto: require('./crypto-js/crypto'),
|
||||
Script: require('./script'),
|
||||
Opcode: require('./opcode'),
|
||||
Transaction: require('./transaction').Transaction,
|
||||
|
|
|
@ -49,11 +49,11 @@ Message.signMessage = function (key, message, compressed) {
|
|||
|
||||
sig = [i].concat(rBa).concat(sBa);
|
||||
|
||||
return conv.bytesToBase64(sig);
|
||||
return conv.bytesToHex(sig);
|
||||
};
|
||||
|
||||
Message.verifyMessage = function (address, sig, message) {
|
||||
sig = conv.base64ToBytes(sig);
|
||||
sig = conv.hexToBytes(sig);
|
||||
sig = ecdsa.parseSigCompact(sig);
|
||||
|
||||
var hash = Message.getHash(message);
|
||||
|
|
|
@ -6,7 +6,7 @@ var Script = function (data) {
|
|||
if (!data) {
|
||||
this.buffer = [];
|
||||
} else if ("string" == typeof data) {
|
||||
this.buffer = Crypto.util.base64ToBytes(data);
|
||||
this.buffer = Crypto.util.hexToBytes(data);
|
||||
} else if (util.isArray(data)) {
|
||||
this.buffer = data;
|
||||
} else if (data instanceof Script) {
|
||||
|
|
|
@ -85,7 +85,7 @@ Transaction.prototype.addOutput = function (address, value) {
|
|||
if (value instanceof BigInteger) {
|
||||
value = value.toByteArrayUnsigned().reverse();
|
||||
while (value.length < 8) value.push(0);
|
||||
} else if (Bitcoin.Util.isArray(value)) {
|
||||
} else if (util.isArray(value)) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,7 @@ Transaction.prototype.getTotalOutValue = function () {
|
|||
var totalValue = BigInteger.ZERO;
|
||||
for (var j = 0; j < this.outs.length; j++) {
|
||||
var txout = this.outs[j];
|
||||
totalValue = totalValue.add(Bitcoin.Util.valueToBigInt(txout.value));
|
||||
totalValue = totalValue.add(util.valueToBigInt(txout.value));
|
||||
}
|
||||
return totalValue;
|
||||
};
|
||||
|
@ -382,9 +382,9 @@ Transaction.prototype.calcImpact = function (wallet) {
|
|||
var valueOut = BigInteger.ZERO;
|
||||
for (var j = 0; j < this.outs.length; j++) {
|
||||
var txout = this.outs[j];
|
||||
var hash = Crypto.util.bytesToBase64(txout.script.simpleOutPubKeyHash());
|
||||
var hash = Crypto.util.bytesToHex(txout.script.simpleOutPubKeyHash());
|
||||
if (wallet.hasHash(hash)) {
|
||||
valueOut = valueOut.add(Bitcoin.Util.valueToBigInt(txout.value));
|
||||
valueOut = valueOut.add(util.valueToBigInt(txout.value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,11 +392,11 @@ Transaction.prototype.calcImpact = function (wallet) {
|
|||
var valueIn = BigInteger.ZERO;
|
||||
for (var j = 0; j < this.ins.length; j++) {
|
||||
var txin = this.ins[j];
|
||||
var hash = Crypto.util.bytesToBase64(txin.script.simpleInPubKeyHash());
|
||||
var hash = Crypto.util.bytesToHex(txin.script.simpleInPubKeyHash());
|
||||
if (wallet.hasHash(hash)) {
|
||||
var fromTx = wallet.txIndex[txin.outpoint.hash];
|
||||
if (fromTx) {
|
||||
valueIn = valueIn.add(Bitcoin.Util.valueToBigInt(fromTx.outs[txin.outpoint.index].value));
|
||||
valueIn = valueIn.add(util.valueToBigInt(fromTx.outs[txin.outpoint.index].value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -412,6 +412,11 @@ Transaction.prototype.calcImpact = function (wallet) {
|
|||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a serialized transaction into a transaction object
|
||||
*/
|
||||
|
||||
Transaction.deserialize = function(buffer) {
|
||||
var pos = 0;
|
||||
var readAsInt = function(bytes) {
|
||||
|
@ -443,7 +448,7 @@ Transaction.deserialize = function(buffer) {
|
|||
for (var i = 0; i < ins; i++) {
|
||||
obj.ins.push({
|
||||
outpoint: {
|
||||
hash: Bitcoin.Util.bytesToBase64(readBytes(32)),
|
||||
hash: util.bytesToHex(readBytes(32)),
|
||||
index: readAsInt(4)
|
||||
},
|
||||
script: new Script(readVarString()),
|
||||
|
@ -461,6 +466,47 @@ Transaction.deserialize = function(buffer) {
|
|||
return new Transaction(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a standard output at some index with the given key
|
||||
*/
|
||||
|
||||
Transaction.prototype.sign = function(index, key, type) {
|
||||
type = type || SIGHASH_ALL;
|
||||
key = new Bitcoin.ECKey(key);
|
||||
var pub = key.getPub(),
|
||||
hash160 = Bitcoin.Util.sha256ripe160(pub),
|
||||
script = Bitcoin.Script.createOutputScript(new Bitcoin.Address(hash160)),
|
||||
hash = this.hashTransactionForSignature( script, index, type),
|
||||
sig = key.sign(hash).concat([type]);
|
||||
this.ins[i].script = Bitcoin.Script.createInputScript(sig,pub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a P2SH output at some index with the given key
|
||||
*/
|
||||
|
||||
Transaction.prototype.p2shsign = function(index, script, key, type) {
|
||||
script = new Bitcoin.Script(script);
|
||||
key = new Bitcoin.ECKey(key);
|
||||
type = type || SIGHASH_ALL;
|
||||
var hash = this.hashTransactionForSignature(script, index, type),
|
||||
sig = key.sign(hash).concat([type]);
|
||||
return sig;
|
||||
}
|
||||
|
||||
Transaction.prototype.multisign = Transaction.prototype.p2shsign;
|
||||
|
||||
// In progress
|
||||
/*Transaction.prototype.validateInput = function(index,script,sig,pub) {
|
||||
script = new Bitcoin.Script(script);
|
||||
|
||||
scriptBytes = bw.h2b(script),
|
||||
scriptObj = new Bitcoin.Script(scriptBytes),
|
||||
hash = txObj.hashTransactionForSignature(scriptObj,i,1);
|
||||
return Bitcoin.ECDSA.verify(hash, bw.h2b(sig),
|
||||
bw.h2b(pub));
|
||||
}*/
|
||||
|
||||
|
||||
var TransactionIn = function (data)
|
||||
{
|
||||
|
|
|
@ -44,12 +44,12 @@ var Wallet = function () {
|
|||
|
||||
if (pub) {
|
||||
if ("string" === typeof pub) {
|
||||
pub = Crypto.util.base64ToBytes(pub);
|
||||
pub = Crypto.util.hexToBytes(pub);
|
||||
}
|
||||
key.setPub(pub);
|
||||
}
|
||||
|
||||
this.addressHashes.push(key.getBitcoinAddress().getHashBase64());
|
||||
this.addressHashes.push(key.getBitcoinAddress().getHash());
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -77,13 +77,13 @@ var Wallet = function () {
|
|||
/**
|
||||
* Get the key chain.
|
||||
*
|
||||
* Returns an array of base64-encoded private values.
|
||||
* Returns an array of hex-encoded private values.
|
||||
*/
|
||||
this.getKeys = function () {
|
||||
var serializedWallet = [];
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
serializedWallet.push(keys[i].toString('base64'));
|
||||
serializedWallet.push(keys[i].toString());
|
||||
}
|
||||
|
||||
return serializedWallet;
|
||||
|
@ -92,13 +92,13 @@ var Wallet = function () {
|
|||
/**
|
||||
* Get the public keys.
|
||||
*
|
||||
* Returns an array of base64-encoded public keys.
|
||||
* Returns an array of hex-encoded public keys.
|
||||
*/
|
||||
this.getPubKeys = function () {
|
||||
var pubs = [];
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
pubs.push(Crypto.util.bytesToBase64(keys[i].getPub()));
|
||||
pubs.push(Crypto.util.bytesToHex(keys[i].getPub()));
|
||||
}
|
||||
|
||||
return pubs;
|
||||
|
@ -171,7 +171,7 @@ var Wallet = function () {
|
|||
* to be signed as the second parameter.
|
||||
*/
|
||||
this.signWithKey = function (pubKeyHash, hash) {
|
||||
pubKeyHash = conv.bytesToBase64(pubKeyHash);
|
||||
pubKeyHash = conv.bytesToHex(pubKeyHash);
|
||||
for (var i = 0; i < this.addressHashes.length; i++) {
|
||||
if (this.addressHashes[i] == pubKeyHash) {
|
||||
return keys[i].sign(hash);
|
||||
|
@ -187,7 +187,7 @@ var Wallet = function () {
|
|||
* wallet.
|
||||
*/
|
||||
this.getPubKeyFromHash = function (pubKeyHash) {
|
||||
pubKeyHash = conv.bytesToBase64(pubKeyHash);
|
||||
pubKeyHash = conv.bytesToHex(pubKeyHash);
|
||||
for (var i = 0; i < this.addressHashes.length; i++) {
|
||||
if (this.addressHashes[i] == pubKeyHash) {
|
||||
return keys[i].getPub();
|
||||
|
@ -222,8 +222,8 @@ Wallet.prototype.process = function (tx) {
|
|||
for (j = 0; j < tx.out.length; j++) {
|
||||
var raw_tx = tx.out[j];
|
||||
var txout = new TransactionOut(raw_tx);
|
||||
// this hash is the base64 hash of the pubkey which is the address the output when to
|
||||
hash = conv.bytesToBase64(txout.script.simpleOutPubKeyHash());
|
||||
// this hash is the hash of the pubkey which is the address the output when to
|
||||
hash = conv.bytesToHex(txout.script.simpleOutPubKeyHash());
|
||||
for (k = 0; k < this.addressHashes.length; k++) {
|
||||
// if our address, then we add the unspent out to a list of unspent outputs
|
||||
if (this.addressHashes[k] === hash) {
|
||||
|
@ -245,7 +245,7 @@ Wallet.prototype.process = function (tx) {
|
|||
|
||||
var txin = new TransactionIn(raw_tx);
|
||||
var pubkey = txin.script.simpleInPubKey();
|
||||
hash = conv.bytesToBase64(util.sha256ripe160(pubkey));
|
||||
hash = conv.bytesToHex(util.sha256ripe160(pubkey));
|
||||
for (k = 0; k < this.addressHashes.length; k++) {
|
||||
if (this.addressHashes[k] === hash) {
|
||||
for (var l = 0; l < this.unspentOuts.length; l++) {
|
||||
|
@ -329,9 +329,9 @@ Wallet.prototype.clearTransactions = function () {
|
|||
* Check to see if a pubKeyHash belongs to this wallet.
|
||||
*/
|
||||
Wallet.prototype.hasHash = function (hash) {
|
||||
if (Bitcoin.Util.isArray(hash)) hash = Crypto.util.bytesToBase64(hash);
|
||||
if (Bitcoin.Util.isArray(hash)) hash = Crypto.util.bytesToHex(hash);
|
||||
|
||||
// TODO: Just create an object with base64 hashes as keys for faster lookup
|
||||
// TODO: Just create an object with hashes as keys for faster lookup
|
||||
for (var k = 0; k < this.addressHashes.length; k++) {
|
||||
if (this.addressHashes[k] === hash) return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue