# This is a combination of 2 commits.

# The first commit's message is:

Add types to Networks and Addresses

# This is the 2nd commit message:

Added types
This commit is contained in:
junderw 2018-12-26 16:13:43 +09:00
parent b4d54af0fe
commit 037fbd8984
No known key found for this signature in database
GPG key ID: B256185D3A971908
5 changed files with 102 additions and 94 deletions

View file

@ -6,8 +6,21 @@ const networks = require('./networks')
const typeforce = require('typeforce')
const types = require('./types')
const payments = require('./payments')
import * as Networks from './networks'
import { Network } from './networks'
function fromBase58Check (address) {
export declare type Base58CheckResult = {
hash: Buffer;
version: number;
}
export declare type Bech32Result = {
version: number;
prefix: string;
data: Buffer;
}
function fromBase58Check (address: string): Base58CheckResult {
const payload = bs58check.decode(address)
// TODO: 4.0.0, move to "toOutputScript"
@ -20,7 +33,7 @@ function fromBase58Check (address) {
return { version: version, hash: hash }
}
function fromBech32 (address) {
function fromBech32 (address: string): Bech32Result {
const result = bech32.decode(address)
const data = bech32.fromWords(result.words.slice(1))
@ -31,7 +44,7 @@ function fromBech32 (address) {
}
}
function toBase58Check (hash, version) {
function toBase58Check (hash: Buffer, version: number): string {
typeforce(types.tuple(types.Hash160bit, types.UInt8), arguments)
const payload = Buffer.allocUnsafe(21)
@ -41,14 +54,14 @@ function toBase58Check (hash, version) {
return bs58check.encode(payload)
}
function toBech32 (data, version, prefix) {
function toBech32 (data: Buffer, version: number, prefix: string): string {
const words = bech32.toWords(data)
words.unshift(version)
return bech32.encode(prefix, words)
}
function fromOutputScript (output, network) {
function fromOutputScript (output: Buffer, network: Network): string { //TODO: Network
network = network || networks.bitcoin
try { return payments.p2pkh({ output, network }).address } catch (e) {}
@ -59,27 +72,28 @@ function fromOutputScript (output, network) {
throw new Error(bscript.toASM(output) + ' has no matching Address')
}
function toOutputScript (address, network) {
function toOutputScript (address: string, network: Network): Buffer {
network = network || networks.bitcoin
let decode
let decodeBase58: Base58CheckResult
let decodeBech32: Bech32Result
try {
decode = fromBase58Check(address)
decodeBase58 = fromBase58Check(address)
} catch (e) {}
if (decode) {
if (decode.version === network.pubKeyHash) return payments.p2pkh({ hash: decode.hash }).output
if (decode.version === network.scriptHash) return payments.p2sh({ hash: decode.hash }).output
if (decodeBase58) {
if (decodeBase58.version === network.pubKeyHash) return payments.p2pkh({ hash: decodeBase58.hash }).output
if (decodeBase58.version === network.scriptHash) return payments.p2sh({ hash: decodeBase58.hash }).output
} else {
try {
decode = fromBech32(address)
decodeBech32 = fromBech32(address)
} catch (e) {}
if (decode) {
if (decode.prefix !== network.bech32) throw new Error(address + ' has an invalid prefix')
if (decode.version === 0) {
if (decode.data.length === 20) return payments.p2wpkh({ hash: decode.data }).output
if (decode.data.length === 32) return payments.p2wsh({ hash: decode.data }).output
if (decodeBech32) {
if (decodeBech32.prefix !== network.bech32) throw new Error(address + ' has an invalid prefix')
if (decodeBech32.version === 0) {
if (decodeBech32.data.length === 20) return payments.p2wpkh({ hash: decodeBech32.data }).output
if (decodeBech32.data.length === 32) return payments.p2wsh({ hash: decodeBech32.data }).output
}
}
}

View file

@ -1,12 +1,12 @@
// https://github.com/feross/buffer/blob/master/index.js#L1127
function verifuint (value, max) {
function verifuint (value: number, max: number): void {
if (typeof value !== 'number') throw new Error('cannot write a non-number as a number')
if (value < 0) throw new Error('specified a negative value for writing an unsigned value')
if (value > max) throw new Error('RangeError: value out of range')
if (Math.floor(value) !== value) throw new Error('value has a fractional component')
}
function readUInt64LE (buffer, offset) {
export function readUInt64LE (buffer: Buffer, offset: number): number {
const a = buffer.readUInt32LE(offset)
let b = buffer.readUInt32LE(offset + 4)
b *= 0x100000000
@ -15,16 +15,10 @@ function readUInt64LE (buffer, offset) {
return b + a
}
function writeUInt64LE (buffer, value, offset) {
export function writeUInt64LE (buffer: Buffer, value: number, offset: number): number {
verifuint(value, 0x001fffffffffffff)
buffer.writeInt32LE(value & -1, offset)
buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4)
return offset + 8
}
module.exports = {
readUInt64LE: readUInt64LE,
writeUInt64LE: writeUInt64LE
}
export {}

View file

@ -9,18 +9,18 @@ const witnessScriptHash = require('./templates/witnessscripthash')
const witnessCommitment = require('./templates/witnesscommitment')
const types = {
P2MS: 'multisig',
NONSTANDARD: 'nonstandard',
NULLDATA: 'nulldata',
P2PK: 'pubkey',
P2PKH: 'pubkeyhash',
P2SH: 'scripthash',
P2WPKH: 'witnesspubkeyhash',
P2WSH: 'witnessscripthash',
WITNESS_COMMITMENT: 'witnesscommitment'
P2MS: <string> 'multisig',
NONSTANDARD: <string> 'nonstandard',
NULLDATA: <string> 'nulldata',
P2PK: <string> 'pubkey',
P2PKH: <string> 'pubkeyhash',
P2SH: <string> 'scripthash',
P2WPKH: <string> 'witnesspubkeyhash',
P2WSH: <string> 'witnessscripthash',
WITNESS_COMMITMENT: <string> 'witnesscommitment'
}
function classifyOutput (script) {
function classifyOutput (script: Buffer): string {
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
if (witnessScriptHash.output.check(script)) return types.P2WSH
if (pubKeyHash.output.check(script)) return types.P2PKH
@ -38,7 +38,7 @@ function classifyOutput (script) {
return types.NONSTANDARD
}
function classifyInput (script, allowIncomplete) {
function classifyInput (script: Buffer, allowIncomplete: boolean): string {
// XXX: optimization, below functions .decompile before use
const chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
@ -51,7 +51,7 @@ function classifyInput (script, allowIncomplete) {
return types.NONSTANDARD
}
function classifyWitness (script, allowIncomplete) {
function classifyWitness (script: Buffer, allowIncomplete: boolean): string {
// XXX: optimization, below functions .decompile before use
const chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
@ -62,10 +62,9 @@ function classifyWitness (script, allowIncomplete) {
return types.NONSTANDARD
}
module.exports = {
input: classifyInput,
output: classifyOutput,
witness: classifyWitness,
types: types
export {
classifyInput as input,
classifyOutput as output,
classifyWitness as witness,
types,
}
export {}

View file

@ -1,30 +1,21 @@
const createHash = require('create-hash')
function ripemd160 (buffer) {
export function ripemd160 (buffer: Buffer): Buffer {
return createHash('rmd160').update(buffer).digest()
}
function sha1 (buffer) {
export function sha1 (buffer: Buffer): Buffer {
return createHash('sha1').update(buffer).digest()
}
function sha256 (buffer) {
export function sha256 (buffer: Buffer): Buffer {
return createHash('sha256').update(buffer).digest()
}
function hash160 (buffer) {
export function hash160 (buffer: Buffer): Buffer {
return ripemd160(sha256(buffer))
}
function hash256 (buffer) {
export function hash256 (buffer: Buffer): Buffer {
return sha256(sha256(buffer))
}
module.exports = {
hash160: hash160,
hash256: hash256,
ripemd160: ripemd160,
sha1: sha1,
sha256: sha256
}
export {}

View file

@ -1,39 +1,49 @@
// https://en.bitcoin.it/wiki/List_of_address_prefixes
// Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731
module.exports = {
bitcoin: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bc',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80
},
regtest: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bcrt',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef
},
testnet: {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'tb',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef
}
export declare type Network = {
messagePrefix: string;
bech32: string;
bip32: bip32;
pubKeyHash: number;
scriptHash: number;
wif: number;
}
declare type bip32 = {
public: number;
private: number;
}
export const bitcoin: Network = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bc',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80
}
export const regtest: Network = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bcrt',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef
}
export const testnet: Network = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'tb',
bip32: {
public: 0x043587cf,
private: 0x04358394
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef
}
export {}