Skip to content

Instantly share code, notes, and snippets.

@shesek
Last active January 9, 2018 15:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shesek/5835695 to your computer and use it in GitHub Desktop.
Save shesek/5835695 to your computer and use it in GitHub Desktop.
Decode Bitcoin raw transactions to bitcoinjs-lib's Transaction object with CoffeeScript
decode_raw_tx = do ->
{ Transaction, TransactionIn, TransactionOut } = Bitcoin
{ bytesToBase64 } = Crypto.util
# Parse an bytearray of length `size` as an integer
# Works for numbers up to 32-bit only
parse_int = (size) -> (bytes) ->
n = 0
n += (bytes.shift() & 0xff) << (8 * i) for i in [0...size]
n
u8 = (bytes) -> bytes.shift()
u16 = parse_int 2
u32 = parse_int 4
# 64 bit numbers are kept as bytes
# (bitcoinjs-lib expects them that way)
u64 = (bytes) -> bytes.splice 0, 8
# https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer
varint = (bytes) ->
switch n = u8 bytes
when 0xfd then u16 bytes
when 0xfe then u32 bytes
when 0xff then u64 bytes
else n
# https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_string
varchar = (bytes) -> bytes.splice 0, varint bytes
(bytes) ->
bytes = bytes.slice() # clone
ver = u32 bytes
throw new Error 'Unsupported version' unless ver is 0x01
tx = new Transaction
# Parse inputs
in_count = varint bytes
for [0...in_count]
tx.addInput new TransactionIn
outpoint:
hash: bytesToBase64 bytes.splice 0, 32
index: u32 bytes
script: varchar bytes
seq: u32 bytes
# Parse outputs
out_count = varint bytes
for [0...out_count]
tx.addOutput new TransactionOut
value: u64 bytes
script: varchar bytes
tx.lock_time = u32 bytes
tx
@cimm
Copy link

cimm commented Apr 3, 2014

@kyledrake Did you find a way to sign raw transactions on the client without using bitcoind? Need to do the same if possible. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment