Transaction: use hash Buffer instead of hex string
This commit is contained in:
parent
2f56e63491
commit
5551c38812
5 changed files with 44 additions and 33 deletions
|
@ -55,11 +55,16 @@ Transaction.prototype.addInput = function(tx, outIndex) {
|
||||||
var hash
|
var hash
|
||||||
|
|
||||||
if (typeof tx === 'string') {
|
if (typeof tx === 'string') {
|
||||||
hash = tx
|
hash = new Buffer(tx, 'hex')
|
||||||
|
assert.equal(hash.length, 32, 'Invalid TX hash')
|
||||||
|
|
||||||
|
// TxHash hex is big-endian, we need little-endian
|
||||||
|
Array.prototype.reverse.call(hash)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(tx instanceof Transaction, 'Unexpected input: ' + tx)
|
assert(tx instanceof Transaction, 'Expected Transaction, got ' + tx)
|
||||||
hash = tx.getId()
|
hash = crypto.hash256(tx.toBuffer())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ins.push(new TransactionIn({
|
this.ins.push(new TransactionIn({
|
||||||
|
@ -142,13 +147,8 @@ Transaction.prototype.toBuffer = function () {
|
||||||
writeUInt32(this.version)
|
writeUInt32(this.version)
|
||||||
writeVarInt(this.ins.length)
|
writeVarInt(this.ins.length)
|
||||||
|
|
||||||
this.ins.forEach(function(txin) {
|
this.ins.forEach(function(txin, i) {
|
||||||
var hash = new Buffer(txin.outpoint.hash, 'hex') // FIXME: Performance: convert on tx.addInput instead
|
writeSlice(txin.outpoint.hash)
|
||||||
|
|
||||||
// TxHash hex is big-endian, we need little-endian
|
|
||||||
Array.prototype.reverse.call(hash)
|
|
||||||
|
|
||||||
writeSlice(hash)
|
|
||||||
writeUInt32(txin.outpoint.index)
|
writeUInt32(txin.outpoint.index)
|
||||||
writeVarInt(txin.script.buffer.length)
|
writeVarInt(txin.script.buffer.length)
|
||||||
writeSlice(txin.script.buffer)
|
writeSlice(txin.script.buffer)
|
||||||
|
@ -240,9 +240,6 @@ Transaction.prototype.clone = function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction.fromBuffer = function(buffer) {
|
Transaction.fromBuffer = function(buffer) {
|
||||||
// Copy because we mutate (reverse TxOutHashs)
|
|
||||||
buffer = new Buffer(buffer)
|
|
||||||
|
|
||||||
var offset = 0
|
var offset = 0
|
||||||
function readSlice(n) {
|
function readSlice(n) {
|
||||||
offset += n
|
offset += n
|
||||||
|
@ -272,10 +269,6 @@ Transaction.fromBuffer = function(buffer) {
|
||||||
|
|
||||||
for (var i = 0; i < vinLen; ++i) {
|
for (var i = 0; i < vinLen; ++i) {
|
||||||
var hash = readSlice(32)
|
var hash = readSlice(32)
|
||||||
|
|
||||||
// TxHash is little-endian, we want big-endian hex
|
|
||||||
Array.prototype.reverse.call(hash)
|
|
||||||
|
|
||||||
var vout = readUInt32()
|
var vout = readUInt32()
|
||||||
var scriptLen = readVarInt()
|
var scriptLen = readVarInt()
|
||||||
var script = readSlice(scriptLen)
|
var script = readSlice(scriptLen)
|
||||||
|
@ -283,7 +276,7 @@ Transaction.fromBuffer = function(buffer) {
|
||||||
|
|
||||||
ins.push(new TransactionIn({
|
ins.push(new TransactionIn({
|
||||||
outpoint: {
|
outpoint: {
|
||||||
hash: hash.toString('hex'),
|
hash: hash,
|
||||||
index: vout
|
index: vout
|
||||||
},
|
},
|
||||||
script: Script.fromBuffer(script),
|
script: Script.fromBuffer(script),
|
||||||
|
|
|
@ -169,9 +169,15 @@ function Wallet(seed, network) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
tx.ins.forEach(function(txIn, i){
|
tx.ins.forEach(function(txIn, i) {
|
||||||
var op = txIn.outpoint
|
var op = txIn.outpoint
|
||||||
var output = op.hash + ':' + op.index
|
|
||||||
|
// copy and convert to big-endian hex
|
||||||
|
var txinHash = new Buffer(op.hash)
|
||||||
|
Array.prototype.reverse.call(txinHash)
|
||||||
|
txinHash = txinHash.toString('hex')
|
||||||
|
|
||||||
|
var output = txinHash + ':' + op.index
|
||||||
|
|
||||||
if(me.outputs[output]) delete me.outputs[output]
|
if(me.outputs[output]) delete me.outputs[output]
|
||||||
})
|
})
|
||||||
|
|
|
@ -147,7 +147,12 @@ describe('Bitcoin-core', function() {
|
||||||
var prevOutIndex = input[1]
|
var prevOutIndex = input[1]
|
||||||
// var prevOutScriptPubKey = input[2] // TODO: we don't have a ASM parser
|
// var prevOutScriptPubKey = input[2] // TODO: we don't have a ASM parser
|
||||||
|
|
||||||
assert.equal(txin.outpoint.hash, prevOutHash)
|
var actualHash = txin.outpoint.hash
|
||||||
|
|
||||||
|
// Test data is big-endian
|
||||||
|
Array.prototype.reverse.call(actualHash)
|
||||||
|
|
||||||
|
assert.equal(actualHash.toString('hex'), prevOutHash)
|
||||||
|
|
||||||
// we read UInt32, not Int32
|
// we read UInt32, not Int32
|
||||||
assert.equal(txin.outpoint.index & 0xffffffff, prevOutIndex)
|
assert.equal(txin.outpoint.index & 0xffffffff, prevOutIndex)
|
||||||
|
@ -184,7 +189,7 @@ describe('Bitcoin-core', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actualHash != undefined) {
|
if (actualHash != undefined) {
|
||||||
// BigEndian test data
|
// Test data is big-endian
|
||||||
Array.prototype.reverse.call(actualHash)
|
Array.prototype.reverse.call(actualHash)
|
||||||
|
|
||||||
assert.equal(actualHash.toString('hex'), expectedHash)
|
assert.equal(actualHash.toString('hex'), expectedHash)
|
||||||
|
|
|
@ -59,7 +59,7 @@ describe('Transaction', function() {
|
||||||
assert.equal(input.sequence, 4294967295)
|
assert.equal(input.sequence, 4294967295)
|
||||||
|
|
||||||
assert.equal(input.outpoint.index, 0)
|
assert.equal(input.outpoint.index, 0)
|
||||||
assert.equal(input.outpoint.hash, "69d02fc05c4e0ddc87e796eee42693c244a3112fffe1f762c3fb61ffcb304634")
|
assert.equal(input.outpoint.hash.toString('hex'), "344630cbff61fbc362f7e1ff2f11a344c29326e4ee96e787dc0d4e5cc02fd069")
|
||||||
|
|
||||||
assert.equal(b2h(input.script.buffer),
|
assert.equal(b2h(input.script.buffer),
|
||||||
"493046022100ef89701f460e8660c80808a162bbf2d676f40a331a243592c36d6bd1f81d6bdf022100d29c072f1b18e59caba6e1f0b8cadeb373fd33a25feded746832ec179880c23901")
|
"493046022100ef89701f460e8660c80808a162bbf2d676f40a331a243592c36d6bd1f81d6bdf022100d29c072f1b18e59caba6e1f0b8cadeb373fd33a25feded746832ec179880c23901")
|
||||||
|
@ -120,7 +120,7 @@ describe('Transaction', function() {
|
||||||
assert.equal(input.sequence, 4294967295)
|
assert.equal(input.sequence, 4294967295)
|
||||||
|
|
||||||
assert.equal(input.outpoint.index, 0)
|
assert.equal(input.outpoint.index, 0)
|
||||||
assert.equal(input.outpoint.hash, "0cb859105100ebc3344f749c835c7af7d7103ec0d8cbc3d8ccbd5d28c3c36b57")
|
assert.equal(input.outpoint.hash.toString('hex'), "576bc3c3285dbdccd8c3cbd8c03e10d7f77a5c839c744f34c3eb00511059b80c")
|
||||||
|
|
||||||
assert.equal(input.script, Script.EMPTY)
|
assert.equal(input.script, Script.EMPTY)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,15 @@ var fixtureTx1Hex = fixtureTxes.prevTx
|
||||||
var fixtureTx2Hex = fixtureTxes.tx
|
var fixtureTx2Hex = fixtureTxes.tx
|
||||||
|
|
||||||
function fakeTxHash(i) {
|
function fakeTxHash(i) {
|
||||||
return "efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe" + i
|
var hash = new Buffer(32)
|
||||||
|
hash.fill(i)
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
function fakeTxId(i) {
|
||||||
|
var hash = fakeTxHash(i)
|
||||||
|
Array.prototype.reverse.call(hash)
|
||||||
|
return hash.toString('hex')
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Wallet', function() {
|
describe('Wallet', function() {
|
||||||
|
@ -263,12 +271,11 @@ describe('Wallet', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('processConfirmedTx', function(){
|
describe('processConfirmedTx', function(){
|
||||||
|
|
||||||
it('does not fail on scripts with no corresponding Address', function() {
|
it('does not fail on scripts with no corresponding Address', function() {
|
||||||
var pubKey = wallet.getPrivateKey(0).pub
|
var pubKey = wallet.getPrivateKey(0).pub
|
||||||
var script = scripts.pubKeyOutput(pubKey)
|
var script = scripts.pubKeyOutput(pubKey)
|
||||||
var tx2 = new Transaction()
|
var tx2 = new Transaction()
|
||||||
tx2.addInput(fakeTxHash(1), 0)
|
tx2.addInput(fakeTxId(1), 0)
|
||||||
|
|
||||||
// FIXME: Transaction doesn't support custom ScriptPubKeys... yet
|
// FIXME: Transaction doesn't support custom ScriptPubKeys... yet
|
||||||
// So for now, we hijack the script with our own, and undefine the cached address
|
// So for now, we hijack the script with our own, and undefine the cached address
|
||||||
|
@ -365,19 +372,19 @@ describe('Wallet', function() {
|
||||||
// set up 3 utxo
|
// set up 3 utxo
|
||||||
utxo = [
|
utxo = [
|
||||||
{
|
{
|
||||||
"hash": fakeTxHash(1),
|
"hash": fakeTxId(1),
|
||||||
"outputIndex": 0,
|
"outputIndex": 0,
|
||||||
"address" : address1,
|
"address" : address1,
|
||||||
"value": 400000 // not enough for value
|
"value": 400000 // not enough for value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hash": fakeTxHash(2),
|
"hash": fakeTxId(2),
|
||||||
"outputIndex": 1,
|
"outputIndex": 1,
|
||||||
"address" : address1,
|
"address" : address1,
|
||||||
"value": 500000 // enough for only value
|
"value": 500000 // enough for only value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hash": fakeTxHash(3),
|
"hash": fakeTxId(3),
|
||||||
"outputIndex": 0,
|
"outputIndex": 0,
|
||||||
"address" : address2,
|
"address" : address2,
|
||||||
"value": 520000 // enough for value and fee
|
"value": 520000 // enough for value and fee
|
||||||
|
@ -415,7 +422,7 @@ describe('Wallet', function() {
|
||||||
it('ignores pending outputs', function(){
|
it('ignores pending outputs', function(){
|
||||||
utxo.push(
|
utxo.push(
|
||||||
{
|
{
|
||||||
"hash": fakeTxHash(4),
|
"hash": fakeTxId(4),
|
||||||
"outputIndex": 0,
|
"outputIndex": 0,
|
||||||
"address" : address2,
|
"address" : address2,
|
||||||
"value": 530000,
|
"value": 530000,
|
||||||
|
@ -437,7 +444,7 @@ describe('Wallet', function() {
|
||||||
var address = wallet.generateAddress()
|
var address = wallet.generateAddress()
|
||||||
|
|
||||||
wallet.setUnspentOutputs([{
|
wallet.setUnspentOutputs([{
|
||||||
hash: fakeTxHash(0),
|
hash: fakeTxId(0),
|
||||||
outputIndex: 0,
|
outputIndex: 0,
|
||||||
address: address,
|
address: address,
|
||||||
value: value
|
value: value
|
||||||
|
@ -459,7 +466,7 @@ describe('Wallet', function() {
|
||||||
var address = wallet.generateAddress()
|
var address = wallet.generateAddress()
|
||||||
|
|
||||||
wallet.setUnspentOutputs([{
|
wallet.setUnspentOutputs([{
|
||||||
hash: fakeTxHash(0),
|
hash: fakeTxId(0),
|
||||||
outputIndex: 0,
|
outputIndex: 0,
|
||||||
address: address,
|
address: address,
|
||||||
value: value
|
value: value
|
||||||
|
|
Loading…
Add table
Reference in a new issue