Bitcoin network protocol streams
This module encodes and decodes low-level network protocol data using streams.
You may want a higher-level module like bitcoin-net, which some things for you such as connection handshakes, sending keepalive pings, etc.
npm install bitcoin-protocol
varnet=require('net')varbp=require('bitcoin-protocol')vardecoder=bp.createDecodeStream()decoder.on('data',function(message){console.log(message)})varencoder=bp.createEncodeStream()varsocket=net.connect(8333,'127.0.0.1',function(){socket.pipe(decoder)encoder.pipe(socket)encoder.write({magic: 0xd9b4bef9,command: 'version',payload: {version: 70012,services: Buffer(8).fill(0),timestamp: Math.round(Date.now()/1000),receiverAddress: {services: Buffer('0100000000000000','hex'),address: '0.0.0.0',port: 8333},senderAddress: {services: Buffer(8).fill(0),address: '0.0.0.0',port: 8333},nonce: Buffer(8).fill(123),userAgent: 'foobar',startHeight: 0,relay: true}})})Creates a stream which parses raw network bytes written to it and outputs message objects.
Opts may contain:
{magic: Number// If provided, the decoder will check if messages' "magic" field matches// this value. If it does not match, the stream will emit an error.}Creates a stream which encodes message objects to raw network bytes.
Opts may contain:
{magic: Number// If provided, the encoder will automatically add the "magic" field to each// message written to it.}Decoder
Emitted by the decoder:
{magic: Number,command: String,length: Number,checksum: Buffer,// 8 bytes,payload: Object// see below for detailed payload formats}Encoder
Written to the encoder:
{magic: Number,// optional if you set this in the optionscommand: String,payload: Object// see below for detailed payload formats}The formats for the objects used as message payloads for the various commands are as follows. See the wiki for more information about these messages.
{version: Number,services: Buffer,// 8 bytestimestamp: Number,receiverAddress: {services: Buffer,// 8 bytesaddress: String,// ipv4 or ipv6port: Number},senderAddress: {services: Buffer,// 8 bytesaddress: String,// ipv4 or ipv6port: Number},nonce: Buffer,// 8 bytesuserAgent: String,startHeight: Number,relay: Boolean}// no payload needed[{time: Number,services: Buffer,// 8 bytesaddress: String,// ipv4 or ipv6port: Number},
...
][{type: Number,hash: Buffer// 32 bytes},
...
]{version: Number,locator: [Buffer// 32 bytes],hashStop: Buffer// 32 bytes}{version: Number,ins: [{hash: Buffer,// 32 bytesindex: Number,script: Buffer,// varying lengthsequence: Number},
...
],outs: [{value: BN,// from 'bn.js' packagescript: Buffer// varying length},
...
],locktime: Number}{header: {version: Number,prevHash: Buffer,// 32 bytesmerkleRoot: Buffer,// 32 bytestimestamp: Number,bits: Number,nonce: Number,},transactions: [{},// same format as 'tx' message
...
]}[{header: {version: Number,prevHash: Buffer,// 32 bytesmerkleRoot: Buffer,// 32 bytestimestamp: Number,bits: Number,nonce: Number,},nTransactions: Number},
...
]{nonce: Buffer// 8 bytes}{message: String,ccode: Number,reason: String,data: Buffer// varying length}{data: Buffer,// varying lengthnHashFuncs: Number,nTweak: Number,nFlags: Number}{data: Buffer// varying length}{header: {version: Number,prevHash: Buffer,// 32 bytesmerkleRoot: Buffer,// 32 bytestimestamp: Number,bits: Number,nonce: Number},numTransactions: Number,hashes: [Buffer// 32 bytes],flags: Buffer// varying length}{payload: Buffer,// varying lengthsignature: Buffer// varying length}