Repository: bitcoinjs/bitcoinjs-lib
Pull request #662 (2016-10-12 14:09:06)

Transaction & block version is int32le
https://en.bitcoin.it/wiki/Protocol_documentation#Block_Headers
https://en.bitcoin.it/wiki/Protocol_documentation#tx

The transaction and block version fields are both int32's (little endian encoded), so technically the range is -2^31 to 2^31 (not zero to 2^32)


Patch:
diff --git a/src/block.js b/src/block.js
index 8e608e85..ba383d5d 100644
--- a/src/block.js
+++ b/src/block.js
@@ -31,8 +31,14 @@ Block.fromBuffer = function (buffer) {
     return i
   }
 
+  function readInt32 () {
+    var i = buffer.readInt32LE(offset)
+    offset += 4
+    return i
+  }
+
   var block = new Block()
-  block.version = readUInt32()
+  block.version = readInt32()
   block.prevHash = readSlice(32)
   block.merkleRoot = readSlice(32)
   block.timestamp = readUInt32()
@@ -93,12 +99,16 @@ Block.prototype.toBuffer = function (headersOnly) {
     offset += slice.length
   }
 
+  function writeInt32 (i) {
+    buffer.writeInt32LE(i, offset)
+    offset += 4
+  }
   function writeUInt32 (i) {
     buffer.writeUInt32LE(i, offset)
     offset += 4
   }
 
-  writeUInt32(this.version)
+  writeInt32(this.version)
   writeSlice(this.prevHash)
   writeSlice(this.merkleRoot)
   writeUInt32(this.timestamp)
diff --git a/src/transaction.js b/src/transaction.js
index a996d554..83027131 100644
--- a/src/transaction.js
+++ b/src/transaction.js
@@ -32,6 +32,12 @@ Transaction.fromBuffer = function (buffer, __noStrict) {
     return i
   }
 
+  function readInt32 () {
+    var i = buffer.readInt32LE(offset)
+    offset += 4
+    return i
+  }
+
   function readUInt64 () {
     var i = bufferutils.readUInt64LE(buffer, offset)
     offset += 8
@@ -49,7 +55,7 @@ Transaction.fromBuffer = function (buffer, __noStrict) {
   }
 
   var tx = new Transaction()
-  tx.version = readUInt32()
+  tx.version = readInt32()
 
   var vinLen = readVarInt()
   for (var i = 0; i < vinLen; ++i) {
@@ -261,10 +267,11 @@ Transaction.prototype.toBuffer = function (buffer, initialOffset) {
   var offset = initialOffset || 0
   function writeSlice (slice) { offset += slice.copy(buffer, offset) }
   function writeUInt32 (i) { offset = buffer.writeUInt32LE(i, offset) }
+  function writeInt32 (i) { offset = buffer.writeInt32LE(i, offset) }
   function writeUInt64 (i) { offset = bufferutils.writeUInt64LE(buffer, i, offset) }
   function writeVarInt (i) { offset += bufferutils.writeVarInt(buffer, i, offset) }
 
-  writeUInt32(this.version)
+  writeInt32(this.version)
   writeVarInt(this.ins.length)
 
   this.ins.forEach(function (txIn) {


Test patch:
diff --git a/test/block.js b/test/block.js
index 97cb7003..fe381205 100644
--- a/test/block.js
+++ b/test/block.js
@@ -6,6 +6,15 @@ var Block = require('../src/block')
 var fixtures = require('./fixtures/block')
 
 describe('Block', function () {
+  describe('version', function () {
+    it('should be interpreted as an int32le', function () {
+      var blockHex = 'ffffffff0000000000000000000000000000000000000000000000000000000000000000414141414141414141414141414141414141414141414141414141414141414101000000020000000300000000'
+      var block = Block.fromHex(blockHex)
+      assert.equal(-1, block.version)
+      assert.equal(1, block.timestamp)
+    })
+  })
+
   describe('calculateTarget', function () {
     fixtures.targets.forEach(function (f) {
       it('returns ' + f.expected + ' for 0x' + f.bits, function () {
diff --git a/test/transaction.js b/test/transaction.js
index b17dbf8a..aab0985a 100644
--- a/test/transaction.js
+++ b/test/transaction.js
@@ -87,6 +87,15 @@ describe('Transaction', function () {
     })
   })
 
+  describe('transactionVersion', function () {
+    it('should be interpreted as an int32le', function () {
+      var txHex = 'ffffffff0000ffffffff'
+      var tx = Transaction.fromHex(txHex)
+      assert.equal(-1, tx.version)
+      assert.equal(0xffffffff, tx.locktime)
+    })
+  })
+
   describe('addInput', function () {
     var prevTxHash
     beforeEach(function () {