From 30ad543c31cb30588b3b3862f57b4e1f64a87d17 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 29 Jan 2016 11:33:00 -0800 Subject: [PATCH] more docs. rename some functions. --- README.md | 87 ++++++++++++++++++++++++++++++++++----------- lib/bcoin/block.js | 8 ++--- lib/bcoin/input.js | 2 +- lib/bcoin/output.js | 2 +- lib/bcoin/script.js | 46 ++++++++++++------------ lib/bcoin/tx.js | 36 +++++++++---------- 6 files changed, 115 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index b0cf3aa6..f82b55f4 100644 --- a/README.md +++ b/README.md @@ -1250,8 +1250,8 @@ Usage: output script and verify input. `index` is the index of the input being verified. `flags` is an object with boolean values. Keys can be of any of bitcoind's script flags in lowercase. i.e. `minimaldata`, `cleanstack`, etc. -- __subscript(s, lastSep)__ - Return script from `lastSep` with codeseparators - removed. +- __getSubscript(s, lastSep)__ - Return script from `lastSep` with + codeseparators removed. - __checksig(msg, sig, key)__ - Verify a signature against a hash and key. - __sign(msg, key, type)__ - Create a bitcoin ecdsa signature from `msg` and a private key. Appends `type` to the signature (the sighash type). @@ -1266,11 +1266,11 @@ Usage: - __createMultisig(keys, m, n)__ - Compile a standard multisig script from array of keys and `m` and `n` value. - __createScripthash(s)__ - Compile a scripthash script from `s`. -- __redeem(s)__ - Grab an deserialize redeem script from input script. -- __standard(s)__ - Return standard output script type. `null` if unknown. +- __getRedeem(s)__ - Grab an deserialize redeem script from input script. +- __getType(s)__ - Return standard output script type. `unknown` if unknown. - __size(s)__ - Return script size in bytes. - __isLocktime(s)__ - Returns true if script is a checklocktimeverify script. -- __lockTime(s)__ - Return locktime value pushed onto the stack if +- __getLockTime(s)__ - Return locktime value pushed onto the stack if checklocktimeverify is used. - __getInputData(s, [prev])__ - Parse input and previous output scripts. Extract as much data as possible. Same format as `Input` getters. @@ -1284,7 +1284,7 @@ Usage: - __isMultisig(s)__ - Returns true if script is multisig. - __isScripthash(s)__ - Returns true if script is pay-to-scripthash. - __isNulldata(s)__ - Returns true if script is nulldata. -- __standardInput(s)__ - Same as `script.standard()`, but works on input +- __getInputType(s)__ - Same as `script.getType()`, but works on input scripts. - __isPubkeyInput(s)__ - Returns true if script is pay-to-pubkey input script. - __isPubkeyhashInput(s)__ - Returns true if script is pay-to-pubkeyhash input @@ -1292,8 +1292,8 @@ Usage: - __isMultisigInput(s)__ - Returns true if script is multisig input script. - __isScripthashInput(s)__ - Returns true if script is pay-to-scripthash input script. -- __coinbase(s)__ - Extract as much data as possible from a coinbase script - including `height`, `extraNonce`, `flags`, and `text`. +- __getCoinbaseData(s)__ - Extract as much data as possible from a coinbase + script including `height`, `extraNonce`, `flags`, and `text`. - __isHash(data)__ - Returns true if data is the length of a ripemd hash. - __isKey(data)__ - Returns true if data is the length of a public key. - __isSignature(data)__ - Returns true if data is the length of a signature. @@ -1310,11 +1310,13 @@ Usage: - __isLowDER(sig)__ - Returns true if sig has a low S value. - __format(s)__ - Format script to make it more human-readable for output and debugging. -- __pushOnly(s)__ - Returns true if script contains only push opcodes. -- __sigops(s, [accurate])__ - Count number of sigops in script. Legacy counting - by default. Set `accurate` to true for accurate counting. -- __sigopsScripthash(s)__ - Count sigops in scripthash input + redeem script. -- __args(s)__ - Return number of expected "input args" for output script type. +- __isPushOnly(s)__ - Returns true if script contains only push opcodes. +- __getSigops(s, [accurate])__ - Count number of sigops in script. Legacy + counting by default. Set `accurate` to true for accurate counting. +- __getScripthashSigops(s)__ - Count sigops in scripthash input + redeem + script. +- __getArgs(s)__ - Return number of expected "input args" for output script + type. #### TXPool (from EventEmitter) @@ -1495,7 +1497,7 @@ Usage: `bcoin.tx([options], [block])` txpool, or an object with txids as its keys and txs as its values. - __isFinal(height, ts)__ - Mimics the bitcoind `IsFinalTx()` function. Checks the locktime and input sequences. Returns true or false. -- __sigops([scripthash], [accurate])__ - Count sigops in transaction. Set +- __getSigops([scripthash], [accurate])__ - Count sigops in transaction. Set `scripthash=true` to count redeem script sigops. Set `accurate=true` for accurate counting instead of legacy counting. - __isStandard()__ - Mimics bitcoind's `IsStandardTx()` function. @@ -1547,11 +1549,15 @@ Usage: `bcoin.wallet(options)` - Inherits all from EventEmitter. - All options. -- TODO ##### Events: -- TODO +- __balance(balance)__ - Emitted when balance is updated. `balance` is in + satoshis (big number). +- __tx(tx)__ - Emitted when a TX is added to the wallet's TXPool. +- __load(ts)__ - Emitted when the TXPool is finished loading. `ts` is the + timestamp of the last transaction in the pool. +- __error(err)__ - Emitted on error. ##### Methods: @@ -1586,6 +1592,12 @@ Usage: `bcoin.wallet(options)` scripts if possible. - __sign(tx)__ - Equivalent to calling both `scriptInputs(tx)` and `signInputs(tx)` in one go. +- __addTX(tx)__ - Add a transaction to the wallet's TXPool. +- __all()__ - Returns all transactions from the TXPool. +- __unspent()__ - Returns all TXes with unspent outputs from the TXPool. +- __pending()__ - Returns all TXes in the TXPool that have yet to be included + in a block. +- __balance()__ - Returns total balance of the TXPool. - __fill(tx)__ - Attempt to `fillUnspent(tx)`. Return `null` if failed to reach total output value. Return `tx` if successful. - __toAddress()__ - Return blockchain-explorer-like data in the format of: @@ -1606,13 +1618,13 @@ Usage: `bcoin.wallet(options)` ##### Static: - Inherits all from Function. -- __Wallet.toSecret(priv, compressed)__ - Convert a private key to a base58 +- __toSecret(priv, compressed)__ - Convert a private key to a base58 string. Mimics the bitcoind CBitcoinSecret object for converting private keys to and from base58 strings. The same format bitcoind uses for `dumpprivkey` and `importprivkey`. -- __Wallet.fromSecret(priv)__ - Convert a base58 private key string to a +- __fromSecret(priv)__ - Convert a base58 private key string to a private key. See above for more information. -- __key2hash([key])__ - Return hash of a public key (byte array). +- __key2hash(key)__ - Return hash of a public key (byte array). - __hash2addr(hash, [prefix])__ - Return address of hash. `prefix` can be `pubkey`, `pubkeyhash`, `multisig`, or `scripthash`. Only `scripthash` actually has a different base58 prefix. @@ -1628,7 +1640,42 @@ Usage: `bcoin.wallet(options)` #### bcoin.utils -TODO +- __toArray(msg, [enc])__ - Converts `msg` to an array. `msg` can be a string + where `enc` can be null (for converting ascii to a byte array) or `hex`. +- __toBase58(arr)__ - Convert a byte array to base58. +- __fromBase58(msg)__ - Convert a base58 string to a byte array. +- __isBase58(msg)__ - Test `msg` to see if it is a base58 string. +- __ripemd160(data, [enc])__ - RIPEMD160 hash function. Returns byte array. +- __sha1(data, [enc])__ - SHA1 hash function. Returns byte array. +- __ripesha(data, [enc])__ - SHA256+RIPEMD160 hash function. Returns byte array. +- __checksum(data, [enc])__ - Create a checksum using a double SHA256. +- __sha256(data, [enc])__ - SHA256 hash function. Returns byte array. +- __dsha256(data, [enc])__ - Double SHA256 hash function. Returns byte array. +- __writeAscii(dst, str, off)__ - Write an ascii string to a byte array. + Returns number of bytes written. +- __readAscii(arr, off, len, printable)__ - Read ascii from a byte array. Set + `printable` to get only printable characters. +- __ascii2array(str)__ - Convert ASCII string to byte array. +- __array2ascii(arr)__ - Convert byte array to ASCII string. +- __array2utf8(arr)__ - Convert byte array to UTF8 string. +- __copy(src, dst, off, [force])__ - Copy data from `src` to `dst` at offset + `off`. Set `force` to increase `dst` size if necessary. +- __stringify(arr)__ - Convert byte array to ASCII string. +- __toHex(arr)__ - Convert byte array to hex string. +- __binaryInsert(list, item, compare, [search])__ - Do a binary insert on + `list`. `compare` is a compare callback. Set `search` for just a binary + search. +- __utils.isEqual(a, b)__ - Compare two byte arrays. +- __utils.nextTick(callback)__ - `process.nextTick` or `setImmediate` if + available. +- __utils.RequestCache__ - TODO. +- __utils.asyncify(callback)__ - Ensure that a callback executes asynchronously + by wrapping it in a nextTick. +- __utils.assert()__ +- __utils.assert.equal()__ +- __utils.btc()__ - Convert satoshis (big number) to BTC string. +- __utils.satoshi()__ - Convert BTC string (must have a decimal point) to + satoshis (big number). #### Packet List diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index df9a629c..6ef5c35f 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -360,7 +360,7 @@ Block.prototype.verifyContext = function verifyContext() { // Make sure the height contained in the coinbase is correct. if (this.version >= 2 && prev.isUpgraded(2)) { - cb = bcoin.script.coinbase(this.txs[0].inputs[0].script); + cb = bcoin.script.getCoinbaseData(this.txs[0].inputs[0].script); // Make sure the coinbase is parseable. if (!cb) { @@ -415,7 +415,7 @@ Block.prototype.verifyContext = function verifyContext() { // Check for tx sigops limits // Bitcoind does not check for this when accepting // a block even though it probably should. - // if (tx.sigops(true) > constants.script.maxTxSigops) { + // if (tx.getSigops(true) > constants.script.maxTxSigops) { // // Block 71036 abused checksig to // // include a huge number of sigops. // utils.debug('Block TX has too many sigops: %s', this.rhash); @@ -427,9 +427,9 @@ Block.prototype.verifyContext = function verifyContext() { // Start counting P2SH sigops once block // timestamps reach March 31st, 2012. if (this.ts >= constants.block.bip16time) - sigops += tx.sigops(true); + sigops += tx.getSigops(true); else - sigops += tx.sigops(); + sigops += tx.getSigops(); if (sigops > constants.script.maxBlockSigops) { utils.debug('Block has too many sigops: %s', this.rhash); diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index c9b0a296..1c5c3e32 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -210,7 +210,7 @@ Input.getData = function getData(input) { } if (input.out && +input.out.hash === 0) { - data = bcoin.script.coinbase(input.script); + data = bcoin.script.getCoinbaseData(input.script); return utils.merge(def, data, { type: 'coinbase', none: true diff --git a/lib/bcoin/output.js b/lib/bcoin/output.js index f8c17bde..c0d9ac4e 100644 --- a/lib/bcoin/output.js +++ b/lib/bcoin/output.js @@ -106,7 +106,7 @@ Output.prototype.__defineGetter__('n', function() { }); Output.prototype.__defineGetter__('lock', function() { - return bcoin.script.lockTime(this.script); + return bcoin.script.getLockTime(this.script); }); Output.prototype.__defineGetter__('flags', function() { diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index f477d80e..8e41781e 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -202,7 +202,7 @@ script.verify = function verify(input, output, tx, i, flags) { flags = {}; if (flags.sigpushonly !== false) { - if (!script.pushOnly(input)) + if (!script.isPushOnly(input)) return false; } @@ -223,7 +223,7 @@ script.verify = function verify(input, output, tx, i, flags) { // If the script is P2SH, execute the real output script if (flags.verifyp2sh !== false && script.isScripthash(output)) { // P2SH can only have push ops in the scriptSig - if (!script.pushOnly(input)) + if (!script.isPushOnly(input)) return false; // Reset the stack @@ -258,7 +258,7 @@ script.verify = function verify(input, output, tx, i, flags) { return true; }; -script.subscript = function subscript(s, lastSep) { +script.getSubscript = function getSubscript(s, lastSep) { var i, res; if (!s) @@ -831,7 +831,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) { type = sig[sig.length - 1]; - subscript = script.subscript(data, lastSep); + subscript = script.getSubscript(data, lastSep); script.removeData(subscript, sig); hash = tx.signatureHash(index, subscript, type); @@ -877,7 +877,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) { if (stack.length < m + 1) return false; - subscript = script.subscript(data, lastSep); + subscript = script.getSubscript(data, lastSep); for (i = 0; i < m; i++) { sig = stack[stack.length - 1 - i]; @@ -1180,20 +1180,20 @@ script.createScripthash = function createScripthash(s) { ]; }; -script.redeem = function redeem(s) { +script.getRedeem = function getRedeem(s) { if (!Array.isArray(s[s.length - 1])) return; return bcoin.script.decode(s[s.length - 1]); }; -script.standard = function standard(s) { +script.getType = function getType(s) { return (script.isPubkey(s) && 'pubkey') || (script.isPubkeyhash(s) && 'pubkeyhash') || (script.isMultisig(s) && 'multisig') || (script.isScripthash(s) && 'scripthash') || (script.isNulldata(s) && 'nulldata') - || null; + || 'unknown'; }; script.isStandard = function isStandard(s) { @@ -1260,7 +1260,7 @@ script.isLockTime = function isLockTime(s) { return script._lockTime(s) != null; }; -script.lockTime = function lockTime(s) { +script.getLockTime = function getLockTime(s) { var lockTime = script._lockTime(s); if (!lockTime) @@ -1272,7 +1272,7 @@ script.lockTime = function lockTime(s) { script.getInputData = function getData(s, prev) { var output, type; - if (prev && !script.isScripthash(prev)) { + if (prev) { output = script.getOutputData(prev); output.side = 'input'; @@ -1305,6 +1305,8 @@ script.getInputData = function getData(s, prev) { type = 'multisig'; else if (script.isScripthashInput(s)) type = 'scripthash'; + else + type = 'unknown'; return script._getInputData(s, type); }; @@ -1353,10 +1355,10 @@ script._getInputData = function _getInputData(s, type) { if (type === 'scripthash') { raw = s[s.length - 1]; redeem = script.decode(raw); - lock = script.lockTime(redeem); + lock = script.getLockTime(redeem); hash = bcoin.wallet.key2hash(raw); address = bcoin.wallet.hash2addr(hash, 'scripthash'); - output = script.getOutputData(script.subscript(redeem)); + output = script.getOutputData(script.getSubscript(redeem)); input = script._getInputData(s.slice(0, -1), output.type); delete input.none; return utils.merge(input, output, { @@ -1617,7 +1619,7 @@ script.isNulldata = function isNulldata(s) { return s[1]; }; -script.standardInput = function standardInput(s) { +script.getInputType = function getInputType(s) { return (script.isPubkeyInput(s) && 'pubkey') || (script.isPubkeyhashInput(s) && 'pubkeyhash') || (script.isMultisigInput(s) && 'multisig') @@ -1753,7 +1755,7 @@ script.isScripthashInput = function isScripthashInput(s, data, strict) { // P2SH redeem scripts can be nonstandard: make // it easier for other functions to parse this. - redeem = script.subscript(script.decode(raw)); + redeem = script.getSubscript(script.decode(raw)); // Get the "real" scriptSig s = s.slice(0, -1); @@ -1775,7 +1777,7 @@ script.isScripthashInput = function isScripthashInput(s, data, strict) { return raw; }; -script.coinbase = function coinbase(s) { +script.getCoinbaseData = function getCoinbaseData(s) { var coinbase, flags; coinbase = { @@ -2089,7 +2091,7 @@ script.format = function format(input, output) { return scripts; }; -script.pushOnly = function pushOnly(s) { +script.isPushOnly = function isPushOnly(s) { var i, op; for (i = 0; i < s.length; i++) { op = s[i]; @@ -2102,7 +2104,7 @@ script.pushOnly = function pushOnly(s) { return true; }; -script.sigops = function sigops(s, accurate) { +script.getSigops = function getSigops(s, accurate) { var i, op; var n = 0; var lastOp = -1; @@ -2128,19 +2130,19 @@ script.sigops = function sigops(s, accurate) { return n; }; -script.sigopsScripthash = function sigopsScripthash(s) { +script.getScripthashSigops = function getScripthashSigops(s) { if (!script.isScripthashInput(s)) return 0; - if (!script.pushOnly(s)) + if (!script.isPushOnly(s)) return 0; - s = script.subscript(script.decode(s[s.length - 1])); + s = script.getSubscript(script.decode(s[s.length - 1])); - return script.sigops(s, true); + return script.getSigops(s, true); }; -script.args = function args(s) { +script.getArgs = function getArgs(s) { var keys, m; if (script.isPubkey(s)) diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index cf4f582b..29598c30 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -188,7 +188,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) { // P2SH if (bcoin.script.isScripthash(s)) { assert(redeem); - s = bcoin.script.subscript(bcoin.script.decode(redeem)); + s = bcoin.script.getSubscript(bcoin.script.decode(redeem)); } else { redeem = null; } @@ -262,7 +262,7 @@ TX.prototype.signature = function signature(index, key, type) { // signing p2sh transactions. if (bcoin.script.isScripthash(s)) { s = bcoin.script.decode(input.script[input.script.length - 1]); - s = bcoin.script.subscript(s); + s = bcoin.script.getSubscript(s); } // Get the hash of the current tx, minus the other @@ -306,7 +306,7 @@ TX.prototype.signInput = function signInput(index, key, type) { // signing p2sh transactions. if (bcoin.script.isScripthash(s)) { s = bcoin.script.decode(input.script[input.script.length - 1]); - s = bcoin.script.subscript(s); + s = bcoin.script.getSubscript(s); // Decrement `len` to avoid the redeem script len--; } @@ -639,7 +639,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) { TX.prototype.getSubscript = function getSubscript(index) { var script = this.outputs[index].script; - return bcoin.script.subscript(script); + return bcoin.script.getSubscript(script); }; TX.prototype.signatureHash = function signatureHash(index, s, type) { @@ -651,7 +651,7 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) { s = this.inputs[index].out.tx.getSubscript(this.inputs[index].out.index); if (bcoin.script.isScripthash(s)) { s = this.inputs[index].script[this.inputs[index.script.length - 1]]; - s = bcoin.script.subscript(bcoin.script.decode(s)); + s = bcoin.script.getSubscript(bcoin.script.decode(s)); } } @@ -671,7 +671,7 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) { // assert(utils.isFinite(type)); // Remove code separators. - // s = script.subscript(s); + // s = script.getSubscript(s); // Remove all signatures. for (i = 0; i < copy.inputs.length; i++) @@ -815,7 +815,7 @@ TX.prototype.maxSize = function maxSize() { // the isMultisig clause. // OP_PUSHDATA2 [redeem] size += 3 + s.length; - s = bcoin.script.subscript(bcoin.script.decode(s)); + s = bcoin.script.getSubscript(bcoin.script.decode(s)); } if (bcoin.script.isPubkey(s)) { @@ -1220,15 +1220,15 @@ TX.prototype.isFinal = function isFinal(height, ts) { return true; }; -TX.prototype.sigops = function sigops(scripthash, accurate) { +TX.prototype.getSigops = function getSigops(scripthash, accurate) { var n = 0; this.inputs.forEach(function(input) { - n += bcoin.script.sigops(input.script, accurate); + n += bcoin.script.getSigops(input.script, accurate); if (scripthash && !this.isCoinbase()) - n += bcoin.script.sigopsScripthash(input.script); + n += bcoin.script.getScripthashSigops(input.script); }, this); this.outputs.forEach(function(output) { - n += bcoin.script.sigops(output.script, accurate); + n += bcoin.script.getSigops(output.script, accurate); }, this); return n; }; @@ -1249,13 +1249,13 @@ TX.prototype.isStandard = function isStandard() { if (script.size(input.script) > 1650) return false; - if (!bcoin.script.pushOnly(input.script)) + if (!bcoin.script.isPushOnly(input.script)) return false; } for (i = 0; i < this.outputs.length; i++) { output = this.outputs[i]; - type = bcoin.script.standard(output.script); + type = bcoin.script.getType(output.script); if (!bcoin.script.isStandard(output.script)) return false; @@ -1298,7 +1298,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) { if (!prev) return false; - args = bcoin.script.args(prev.script); + args = bcoin.script.getArgs(prev.script); if (args < 0) return false; @@ -1319,15 +1319,15 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) { if (!Array.isArray(s)) return false; - s = bcoin.script.subscript(bcoin.script.decode(s)); + s = bcoin.script.getSubscript(bcoin.script.decode(s)); - if (bcoin.script.standard(s)) { - targs = bcoin.script.args(s); + if (bcoin.script.getType(s) !== 'unknown') { + targs = bcoin.script.getArgs(s); if (targs < 0) return false; args += targs; } else { - return script.sigops(s, true) <= constants.script.maxScripthashSigops; + return script.getSigops(s, true) <= constants.script.maxScripthashSigops; } }