Skip to content

Commit

Permalink
Add ZCash support in bitcoinjs-lib
Browse files Browse the repository at this point in the history
Summary:
Add ZCash support when creating transactions

Merge branch 'add-zcash-support' of github.com:BitGo/bitcoinjs-lib into add-zcash-support

Merge branch 'add-zcash-support' of github.com:BitGo/bitcoinjs-lib into add-zcash-support

Add zcash to the network file

Merge branch 'add-zcash-support' of github.com:BitGo/bitcoinjs-lib into add-zcash-support

Reviewers: tyler, taylor, arik, alex

Reviewed By: taylor, arik, alex

Subscribers: taylor

Differential Revision: https://phabricator.bitgo.com/D8644
  • Loading branch information
argjv committed May 18, 2018
1 parent 5461979 commit 1227942
Show file tree
Hide file tree
Showing 19 changed files with 518 additions and 32 deletions.
3 changes: 3 additions & 0 deletions .arcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"phabricator.uri" : "https://phabricator.bitgo.com"
}
19 changes: 19 additions & 0 deletions .arclint
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"linters": {
"filename": {
"type": "filename"
},
"generated": {
"type": "generated"
},
"merge-conflict": {
"type": "merge-conflict"
},
"nolint": {
"type": "nolint"
},
"spelling": {
"type": "spelling"
}
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ coverage
node_modules
.nyc_output
npm-debug.log
.idea
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bitgo-bitcoinjs-lib",
"version": "3.1.1",
"version": "3.2.0",
"description": "Client-side Bitcoin JavaScript library",
"main": "./src/index.js",
"engines": {
Expand Down
23 changes: 16 additions & 7 deletions src/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ function fromBase58Check (address) {

// TODO: 4.0.0, move to "toOutputScript"
if (payload.length < 21) throw new TypeError(address + ' is too short')
if (payload.length > 21) throw new TypeError(address + ' is too long')
if (payload.length > 22) throw new TypeError(address + ' is too long')

var version = payload.readUInt8(0)
var hash = payload.slice(1)
var multibyte = payload.length === 22
var offset = multibyte ? 2 : 1

var version = multibyte ? payload.readUInt16BE(0) : payload[0]
var hash = payload.slice(offset)

return { version: version, hash: hash }
}
Expand All @@ -32,11 +35,17 @@ function fromBech32 (address) {
}

function toBase58Check (hash, version) {
typeforce(types.tuple(types.Hash160bit, types.UInt8), arguments)
typeforce(types.tuple(types.Hash160bit, types.UInt16), arguments)

// Zcash adds an extra prefix resulting in a bigger (22 bytes) payload. We identify them Zcash by checking if the
// version is multibyte (2 bytes instead of 1)
var multibyte = version > 0xff
var size = multibyte ? 22 : 21
var offset = multibyte ? 2 : 1

var payload = Buffer.allocUnsafe(21)
payload.writeUInt8(version, 0)
hash.copy(payload, 1)
var payload = Buffer.allocUnsafe(size)
multibyte ? payload.writeUInt16BE(version, 0) : payload.writeUInt8(version, 0)
hash.copy(payload, offset)

return bs58check.encode(payload)
}
Expand Down
2 changes: 1 addition & 1 deletion src/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Block.fromBuffer = function (buffer) {
}

function readTransaction () {
var tx = Transaction.fromBuffer(buffer.slice(offset), true)
var tx = Transaction.fromBuffer(buffer.slice(offset), null, true)
offset += tx.byteLength()
return tx
}
Expand Down
28 changes: 28 additions & 0 deletions src/coins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Coins supported by bitgo-bitcoinjs-lib

const typeforce = require('typeforce')

const coins = {
BCH: 'bch',
BTC: 'btc',
BTG: 'btg',
ZEC: 'zec'
}

coins.isBitcoin = function (value) {
return typeforce.String(value) && value === coins.BTC
}

coins.isBitcoinCash = function (value) {
return typeforce.String(value) && value === coins.BCH
}

coins.isBitcoinGold = function (value) {
return typeforce.String(value) && value === coins.BTG
}

coins.isZcash = function (value) {
return typeforce.String(value) && value === coins.ZEC
}

module.exports = coins
2 changes: 1 addition & 1 deletion src/ecpair.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ ECPair.fromWIF = function (string, network) {
if (types.Array(network)) {
network = network.filter(function (x) {
return version === x.wif
}).pop()
}).pop() // We should not use pop since it depends on the order of the networks for the same wif

if (!network) throw new Error('Unknown network version')

Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
TransactionBuilder: require('./transaction_builder'),

address: require('./address'),
coins: require('./coins'),
crypto: require('./crypto'),
networks: require('./networks'),
opcodes: require('bitcoin-ops'),
Expand Down
22 changes: 22 additions & 0 deletions src/networks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@
// Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731

module.exports = {
zcash: {
messagePrefix: '\x18ZCash Signed Message:\n',
bech32: 'bc',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x1cb8,
scriptHash: 0x1cbd,
wif: 0x80
},
zcashTest: {
messagePrefix: '\x18ZCash Signed Message:\n',
bech32: 'tb',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x1d25,
scriptHash: 0x1cba,
wif: 0xef
},
bitcoingold: {
messagePrefix: '\x18Bitcoin Gold Signed Message:\n',
bip32: {
Expand Down
11 changes: 8 additions & 3 deletions src/templates/nulldata.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ function check (script) {
check.toJSON = function () { return 'null data output' }

function encode (data) {
typeforce(types.Buffer, data)
// Allow arrays types since decompile returns an array too
typeforce(typeforce.oneOf(types.Buffer, types.Array), data)

return bscript.compile([OPS.OP_RETURN, data])
return bscript.compile([OPS.OP_RETURN].concat(data))
}

function decode (buffer) {
typeforce(check, buffer)

return buffer.slice(2)
var chunks = bscript.decompile(buffer)

chunks.shift()

return chunks.length === 1 ? chunks[0] : chunks
}

module.exports = {
Expand Down
Loading

0 comments on commit 1227942

Please sign in to comment.