Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions src/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function Block () {
this.nonce = 0
}

Block.fromBuffer = function (buffer) {
Block.fromBuffer = function (buffer, network) {
assert(buffer.length >= 80, 'Buffer too small (< 80 bytes)')

var offset = 0
Expand Down Expand Up @@ -46,7 +46,7 @@ Block.fromBuffer = function (buffer) {

// FIXME: poor performance
function readTransaction () {
var tx = Transaction.fromBuffer(buffer.slice(offset), true)
var tx = Transaction.fromBuffer(buffer.slice(offset), true, network)

offset += tx.toBuffer().length
return tx
Expand All @@ -60,11 +60,18 @@ Block.fromBuffer = function (buffer) {
block.transactions.push(tx)
}

// Read block signature (vchBlockSig) for PoS coins.
block.blockSig = null
if (offset < buffer.length) {
var blockSigSize = readVarInt()
block.blockSig = readSlice(blockSigSize)
}

return block
}

Block.fromHex = function (hex) {
return Block.fromBuffer(new Buffer(hex, 'hex'))
Block.fromHex = function (hex, network) {
return Block.fromBuffer(new Buffer(hex, 'hex'), network)
}

Block.prototype.getHash = function () {
Expand Down Expand Up @@ -110,7 +117,15 @@ Block.prototype.toBuffer = function (headersOnly) {
return tx.toBuffer()
})

return Buffer.concat([buffer, txLenBuffer].concat(txBuffers))
var ret = Buffer.concat([buffer, txLenBuffer].concat(txBuffers))

// Block Signature.
if (this.blockSig) {
var blockSigLenBuffer = bufferutils.varIntBuffer(this.blockSig.length)
ret = Buffer.concat([ret, blockSigLenBuffer, this.blockSig])
}

return ret
}

Block.prototype.toHex = function (headersOnly) {
Expand Down
24 changes: 20 additions & 4 deletions src/networks.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ module.exports = {
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
dustThreshold: 546 // https://github.com/bitcoin/bitcoin/blob/v0.9.2/src/core.h#L151-L162
dustThreshold: 546, // https://github.com/bitcoin/bitcoin/blob/v0.9.2/src/core.h#L151-L162
isPoS: false
},
testnet: {
magic: 0xd9b4bef9,
Expand All @@ -24,7 +25,8 @@ module.exports = {
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
dustThreshold: 546
dustThreshold: 546,
isPoS: false
},
litecoin: {
magic: 0xd9b4bef9,
Expand All @@ -36,7 +38,8 @@ module.exports = {
pubKeyHash: 0x30,
scriptHash: 0x05,
wif: 0xb0,
dustThreshold: 0 // https://github.com/litecoin-project/litecoin/blob/v0.8.7.2/src/main.cpp#L360-L365
dustThreshold: 0, // https://github.com/litecoin-project/litecoin/blob/v0.8.7.2/src/main.cpp#L360-L365
isPoS: false
},
dogecoin: {
messagePrefix: '\x19Dogecoin Signed Message:\n',
Expand All @@ -47,6 +50,19 @@ module.exports = {
pubKeyHash: 0x1e,
scriptHash: 0x16,
wif: 0x9e,
dustThreshold: 0 // https://github.com/dogecoin/dogecoin/blob/v1.7.1/src/core.h#L155-L160
dustThreshold: 0, // https://github.com/dogecoin/dogecoin/blob/v1.7.1/src/core.h#L155-L160
isPoS: false
},
peercoin: {
messagePrefix: '\x17PPcoin Signed Message:\n',
bip32: {
public: 0x01da950b, // start with "Ppub..."
private: 0x01da90d0 // start with "Pprv..."
},
pubKeyHash: 0x37,
scriptHash: 0x75,
wif: 0xb7,
dustThreshold: 0,
isPoS: true
}
}
21 changes: 14 additions & 7 deletions src/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ var bufferutils = require('./bufferutils')
var crypto = require('./crypto')
var typeForce = require('typeforce')
var opcodes = require('./opcodes')
var networks = require('./networks')

var Script = require('./script')

function Transaction () {
function Transaction (network) {
this.network = network || networks.bitcoin
this.version = 1
this.time = Math.floor(new Date().getTime() / 1000)
this.locktime = 0
this.ins = []
this.outs = []
Expand All @@ -19,7 +22,8 @@ Transaction.SIGHASH_NONE = 0x02
Transaction.SIGHASH_SINGLE = 0x03
Transaction.SIGHASH_ANYONECANPAY = 0x80

Transaction.fromBuffer = function (buffer, __disableAssert) {
Transaction.fromBuffer = function (buffer, __disableAssert, network) {
network = network || networks.bitcoin
var offset = 0
function readSlice (n) {
offset += n
Expand Down Expand Up @@ -52,8 +56,9 @@ Transaction.fromBuffer = function (buffer, __disableAssert) {
return new Script(readSlice(readVarInt()), [])
}

var tx = new Transaction()
var tx = new Transaction(network)
tx.version = readUInt32()
if (network.isPoS) tx.time = readUInt32()

var vinLen = readVarInt()
for (var i = 0; i < vinLen; ++i) {
Expand Down Expand Up @@ -93,8 +98,8 @@ Transaction.fromBuffer = function (buffer, __disableAssert) {
return tx
}

Transaction.fromHex = function (hex) {
return Transaction.fromBuffer(new Buffer(hex, 'hex'))
Transaction.fromHex = function (hex, network) {
return Transaction.fromBuffer(new Buffer(hex, 'hex'), null, network)
}

Transaction.isCoinbaseHash = function (buffer) {
Expand Down Expand Up @@ -145,7 +150,7 @@ Transaction.prototype.byteLength = function () {
}

return (
8 +
(this.network.isPoS ? 12 : 8) +
bufferutils.varIntSize(this.ins.length) +
bufferutils.varIntSize(this.outs.length) +
this.ins.reduce(function (sum, input) { return sum + 40 + scriptSize(input.script) }, 0) +
Expand All @@ -154,8 +159,9 @@ Transaction.prototype.byteLength = function () {
}

Transaction.prototype.clone = function () {
var newTx = new Transaction()
var newTx = new Transaction(this.network)
newTx.version = this.version
newTx.time = this.time
newTx.locktime = this.locktime

newTx.ins = this.ins.map(function (txIn) {
Expand Down Expand Up @@ -295,6 +301,7 @@ Transaction.prototype.toBuffer = function () {
}

writeUInt32(this.version)
if (this.network.isPoS) writeUInt32(this.time)
writeVarInt(this.ins.length)

this.ins.forEach(function (txIn) {
Expand Down
9 changes: 6 additions & 3 deletions src/transaction_builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var bcrypto = require('./crypto')
var bufferutils = require('./bufferutils')
var ops = require('./opcodes')
var scripts = require('./scripts')
var networks = require('./networks')

var Address = require('./address')
var ECPair = require('./ecpair')
Expand Down Expand Up @@ -83,20 +84,22 @@ function extractInput (txIn) {
}
}

function TransactionBuilder () {
function TransactionBuilder (network) {
this.network = network || networks.bitcoin
this.prevTxMap = {}
this.prevOutScripts = {}
this.prevOutTypes = {}

this.inputs = []
this.tx = new Transaction()
this.tx = new Transaction(network)
}

TransactionBuilder.fromTransaction = function (transaction) {
var txb = new TransactionBuilder()
var txb = new TransactionBuilder(transaction.network)

// Copy other transaction fields
txb.tx.version = transaction.version
txb.tx.time = transaction.time
txb.tx.locktime = transaction.locktime

// Extract/add inputs
Expand Down
13 changes: 7 additions & 6 deletions test/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var assert = require('assert')

var networks = require('../src/networks')
var Block = require('../src/block')

var fixtures = require('./fixtures/block')
Expand All @@ -10,7 +11,7 @@ describe('Block', function () {
describe('fromBuffer/fromHex', function () {
fixtures.valid.forEach(function (f) {
it('imports the block: ' + f.description + ' correctly', function () {
var block = Block.fromHex(f.hex)
var block = Block.fromHex(f.hex, networks[f.network])

assert.strictEqual(block.version, f.version)
assert.strictEqual(block.prevHash.toString('hex'), f.prevHash)
Expand All @@ -24,7 +25,7 @@ describe('Block', function () {
fixtures.invalid.forEach(function (f) {
it('throws on ' + f.exception, function () {
assert.throws(function () {
Block.fromHex(f.hex)
Block.fromHex(f.hex, networks[f.network])
}, new RegExp(f.exception))
})
})
Expand All @@ -35,7 +36,7 @@ describe('Block', function () {
var block

beforeEach(function () {
block = Block.fromHex(f.hex)
block = Block.fromHex(f.hex, networks[f.network])
})

it('exports the block: ' + f.description + ' correctly', function () {
Expand All @@ -49,7 +50,7 @@ describe('Block', function () {
var block

beforeEach(function () {
block = Block.fromHex(f.hex)
block = Block.fromHex(f.hex, networks[f.network])
})

it('calculates ' + f.hash + ' for the block: ' + f.description, function () {
Expand All @@ -63,7 +64,7 @@ describe('Block', function () {
var block

beforeEach(function () {
block = Block.fromHex(f.hex)
block = Block.fromHex(f.hex, networks[f.network])
})

it('calculates ' + f.id + ' for the block: ' + f.description, function () {
Expand All @@ -77,7 +78,7 @@ describe('Block', function () {
var block

beforeEach(function () {
block = Block.fromHex(f.hex)
block = Block.fromHex(f.hex, networks[f.network])
})

it('returns UTC date of ' + f.id, function () {
Expand Down
17 changes: 17 additions & 0 deletions test/fixtures/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"valid": [
{
"description": "Coinbase only - Headers only",
"network": "bitcoin",
"hash": "55388f8f9b326bd0b8e50fbe44c1903d4be14febcfad4dffa50c846c00000000",
"id": "000000006c840ca5ff4dadcfeb4fe14b3d90c144be0fe5b8d06b329b8f8f3855",
"version": 2,
Expand All @@ -14,6 +15,7 @@
},
{
"description": "Coinbase only",
"network": "bitcoin",
"hash": "55388f8f9b326bd0b8e50fbe44c1903d4be14febcfad4dffa50c846c00000000",
"id": "000000006c840ca5ff4dadcfeb4fe14b3d90c144be0fe5b8d06b329b8f8f3855",
"version": 2,
Expand All @@ -24,8 +26,22 @@
"nonce": 3760981266,
"hex": "020000003385c4b2a3499669987f5d04fa4127b59dbf2ee625694fa0bf08000000000000cf52f0ed6571367818a801a169e64030d8cab1a9f17e27170a6924127e19dbb8eba43e54ffff001d12052ce00101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2403089904174b6e434d696e65724251521defe5cdcf04ad543ea4eb0101000000165e0000ffffffff0100f90295000000001976a9149e8985f82bc4e0f753d0492aa8d11cc39925774088ac00000000"
},
{
"description": "Coinbase only (PoS-type; Peercoin #1)",
"network": "peercoin",
"hash": "586629ff7567a5fbc5409eec427f7610755c51ba7150af24e0e40b0000000000",
"id": "00000000000be4e024af5071ba515c7510767f42ec9e40c5fba56775ff296658",
"version": 1,
"prevHash": "e327cd80c8b17efda4ea08c5877e95d877462ab66349d5667167fe3200000000",
"merkleRoot": "68f623d206a1bde3b0382e97af9c0b6bfa708ca4c25f339953e134ff4ee8da1b",
"timestamp": 1345400356,
"bits": 469827583,
"nonce": 1915373966,
"hex": "01000000e327cd80c8b17efda4ea08c5877e95d877462ab66349d5667167fe320000000068f623d206a1bde3b0382e97af9c0b6bfa708ca4c25f339953e134ff4ee8da1b242e3150ffff001c8e492a720101000000742c3150010000000000000000000000000000000000000000000000000000000000000000ffffffff0f04242e3150021a02062f503253482fffffffff017028ff9400000000232102e5d9735f12cc4adfce708445c9e109dc945a135377bddf6a6f856757c88eecb3ac0000000047304502210091c860f869ade3c1536a94c7f9e51ae72aa04380f6d22198320d733a5bea6ac5022035e4daaff5b11f4dbd93a02cc79d207cbe33199c1c05fde9df8822d92e5c20c1"
},
{
"description": "Low number of transactions",
"network": "bitcoin",
"hash": "f0ca57cf84cc953194cd87de4bd9142720a056dc6f27484767f3e85e00000000",
"id": "000000005ee8f3674748276fdc56a0202714d94bde87cd943195cc84cf57caf0",
"version": 2,
Expand All @@ -38,6 +54,7 @@
},
{
"description": "Medium number of transactions",
"network": "bitcoin",
"hash": "0cccf0b884a20113ea2c53a381dacc92a68ae9db1cf86525eb259f0c00000000",
"id": "000000000c9f25eb2565f81cdbe98aa692ccda81a3532cea1301a284b8f0cc0c",
"version": 2,
Expand Down
Loading