mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-22 00:52:01 -07:00
Compare commits
35
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c74b675bc9 | ||
|
|
d0129c01f3 | ||
|
|
ad40607e5b | ||
|
|
a4f0ee6e42 | ||
|
|
0b70ea108b | ||
|
|
cef9a3cf52 | ||
|
|
c216f6c075 | ||
|
|
b53f6bcfc6 | ||
|
|
cbc834cc1a | ||
|
|
1cb5fe069b | ||
|
|
425e2cbbc1 | ||
|
|
9e92f77523 | ||
|
|
dc85bb4cfe | ||
|
|
92960b6957 | ||
|
|
6f34ea286a | ||
|
|
26f39023c4 | ||
|
|
4a3baca72d | ||
|
|
fe37c3ca43 | ||
|
|
ff4ffab670 | ||
|
|
400e7b31a8 | ||
|
|
360fca0475 | ||
|
|
ef7056ee7a | ||
|
|
d221077786 | ||
|
|
046ab78c6a | ||
|
|
29e90915e7 | ||
|
|
3d85dbfb22 | ||
|
|
2c0fa9dfbd | ||
|
|
6ca1d729dc | ||
|
|
c095af8a29 | ||
|
|
89e4ea1635 | ||
|
|
85a34a8305 | ||
|
|
ef6cfe4409 | ||
|
|
a29d6ed26a | ||
|
|
fa58a0764c | ||
|
|
ee7ab54d26 |
@@ -118,3 +118,5 @@ Copies of this repository are also published on [IPFS](https://ipfs.io).
|
||||
## License
|
||||
|
||||
[MIT](LICENSE.md)
|
||||
|
||||
test
|
||||
|
||||
Generated
+3199
-5122
File diff suppressed because it is too large
Load Diff
+44
-44
@@ -18,7 +18,8 @@
|
||||
"test:integration:local:abc": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 test/integration && mocha --timeout 30000 test/integration/chains/abc/",
|
||||
"test:integration:local:bchn": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 test/integration/ && mocha --timeout 30000 test/integration/chains/bchn/",
|
||||
"test:integration:local:testnet": "RESTURL=http://localhost:4000/v5/ mocha --timeout 30000 test/integration/chains/testnet",
|
||||
"test:integration:decatur:bchn": "export RESTURL=http://192.168.0.36:3000/v5/ && mocha --timeout 30000 test/integration/",
|
||||
"test:integration:decatur:bchn": "export RESTURL=http://192.168.0.36:3000/v5/ && mocha --timeout 30000 test/integration/ && mocha --timeout 30000 test/integration/chains/bchn/",
|
||||
"test:integration:decatur:abc": "export RESTURL=http://192.168.0.38:3000/v5/ && mocha --timeout 30000 test/integration && mocha --timeout 30000 test/integration/chains/abc/",
|
||||
"test:integration:temp:bchn": "export RESTURL=http://157.90.174.219:3000/v5/ && mocha --timeout 30000 test/integration/",
|
||||
"test:temp": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 -g '#Encryption' test/integration/",
|
||||
"test:temp2": "mocha --timeout=30000 -g '#TransactionLib' test/unit/",
|
||||
@@ -36,53 +37,52 @@
|
||||
"url": "git+https://github.com/Permissionless-Software-Foundation/bch-js.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@psf/bip21": "^2.0.1",
|
||||
"@psf/bip32-utils": "^1.0.0",
|
||||
"@psf/bitcoincash-ops": "^2.0.0",
|
||||
"@psf/bitcoincashjs-lib": "^4.0.2",
|
||||
"@psf/coininfo": "^4.0.0",
|
||||
"@uppy/core": "^1.10.4",
|
||||
"@uppy/tus": "^1.5.12",
|
||||
"axios": "^0.21.1",
|
||||
"bc-bip68": "^1.0.5",
|
||||
"bchaddrjs-slp": "^0.2.5",
|
||||
"bigi": "^1.4.2",
|
||||
"bignumber.js": "^9.0.0",
|
||||
"bip-schnorr": "^0.3.0",
|
||||
"bip38": "^2.0.2",
|
||||
"bip39": "^3.0.2",
|
||||
"bip66": "^1.1.5",
|
||||
"bitcoinjs-message": "^2.0.0",
|
||||
"bs58": "^4.0.1",
|
||||
"ecashaddrjs": "^1.0.7",
|
||||
"ini": "^1.3.8",
|
||||
"randombytes": "^2.0.6",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"satoshi-bitcoin": "^1.0.4",
|
||||
"@psf/bip21": "2.0.1",
|
||||
"@chris.troutner/bip32-utils": "1.0.5",
|
||||
"@psf/bitcoincash-ops": "2.0.0",
|
||||
"@psf/bitcoincashjs-lib": "4.0.2",
|
||||
"@psf/coininfo": "4.0.0",
|
||||
"@uppy/core": "1.10.4",
|
||||
"@uppy/tus": "1.5.12",
|
||||
"axios": "^0.21.4",
|
||||
"bc-bip68": "1.0.5",
|
||||
"bchaddrjs-slp": "0.2.5",
|
||||
"bigi": "1.4.2",
|
||||
"bignumber.js": "9.0.0",
|
||||
"bip-schnorr": "0.3.0",
|
||||
"bip38": "2.0.2",
|
||||
"bip39": "3.0.2",
|
||||
"bip66": "1.1.5",
|
||||
"bitcoinjs-message": "2.0.0",
|
||||
"bs58": "4.0.1",
|
||||
"ecashaddrjs": "1.0.7",
|
||||
"ini": "1.3.8",
|
||||
"randombytes": "2.0.6",
|
||||
"safe-buffer": "5.1.2",
|
||||
"satoshi-bitcoin": "1.0.4",
|
||||
"slp-mdm": "0.0.6",
|
||||
"slp-parser": "0.0.4",
|
||||
"wif": "^2.0.6"
|
||||
"wif": "2.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"apidoc": "^0.17.7",
|
||||
"assert": "^2.0.0",
|
||||
"chai": "^4.1.2",
|
||||
"coveralls": "^3.0.2",
|
||||
"eslint": "5.16.0",
|
||||
"eslint-config-prettier": "^6.0.0",
|
||||
"eslint-config-standard": "^14.1.0",
|
||||
"eslint-plugin-node": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"husky": "^4.3.6",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"mocha": "^9.1.3",
|
||||
"node-mocks-http": "^1.7.0",
|
||||
"nyc": "^15.1.0",
|
||||
"prettier": "^1.18.2",
|
||||
"semantic-release": "^17.3.9",
|
||||
"sinon": "^7.3.2",
|
||||
"standard": "^16.0.3"
|
||||
"apidoc": "0.17.7",
|
||||
"assert": "2.0.0",
|
||||
"chai": "4.1.2",
|
||||
"coveralls": "3.0.2",
|
||||
"eslint": "7.17.0",
|
||||
"eslint-config-prettier": "7.1.0",
|
||||
"eslint-config-standard": "16.0.3",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-prettier": "3.3.1",
|
||||
"eslint-plugin-standard": "4.0.0",
|
||||
"husky": "^4.3.8",
|
||||
"lodash.clonedeep": "4.5.0",
|
||||
"mocha": "9.1.3",
|
||||
"node-mocks-http": "1.7.0",
|
||||
"nyc": "15.1.0",
|
||||
"semantic-release": "18.0.0",
|
||||
"sinon": "9.2.2",
|
||||
"standard": "^16.0.4"
|
||||
},
|
||||
"apidoc": {
|
||||
"title": "bch-js",
|
||||
|
||||
+3
-3
@@ -223,7 +223,7 @@ class Address {
|
||||
* @api Address.hash160ToCash() hash160ToCash()
|
||||
* @apiName hash160ToCash
|
||||
* @apiGroup Address
|
||||
* @apiDescription Convert hash160 to cash address.
|
||||
* @apiDescription Convert hash160 to cash address. Accepts either hexadecimal or buffer.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* bchjs.Address.hash160ToCash("573d93b475be4f1925f3b74ed951201b0147eac1")
|
||||
@@ -794,13 +794,13 @@ class Address {
|
||||
* @apiDescription Detect an addess from an OutputScript..
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* const script = bchjs.Script.encode([
|
||||
* const scriptBuffer = bchjs.Script.encode([
|
||||
* Buffer.from("BOX", "ascii"),
|
||||
* bchjs.Script.opcodes.OP_CAT,
|
||||
* Buffer.from("BITBOX", "ascii"),
|
||||
* bchjs.Script.opcodes.OP_EQUAL
|
||||
* ]);
|
||||
* const p2sh_hash160 = bchjs.Crypto.hash160(script);
|
||||
* const p2sh_hash160 = bchjs.Crypto.hash160(scriptBuffer);
|
||||
* const scriptPubKey = bchjs.Script.scriptHash.output.encode(p2sh_hash160);
|
||||
*
|
||||
* // mainnet address from output script
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ class Crypto {
|
||||
* @api Crypto.hash256() hash256()
|
||||
* @apiName hash256
|
||||
* @apiGroup Crypto
|
||||
* @apiDescription Utility for creating double sha256 hash digests of data.
|
||||
* @apiDescription Utility for creating double sha256 hash digests of buffer encoded data.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* // buffer from hex
|
||||
@@ -86,7 +86,7 @@ class Crypto {
|
||||
* @api Crypto.hash160() hash160()
|
||||
* @apiName hash160
|
||||
* @apiGroup Crypto
|
||||
* @apiDescription Utility for creating ripemd160(sha256()) hash digests of data.
|
||||
* @apiDescription Utility for creating ripemd160(sha256()) hash digests of buffer encoded data.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* // buffer from hex
|
||||
|
||||
+2
-2
@@ -142,7 +142,7 @@ class ElectrumX {
|
||||
* (async () => {
|
||||
* try {
|
||||
* let balance = await bchjs.Electrumx.balance('bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf');
|
||||
* console.log(utxo);
|
||||
* console.log(balance);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
@@ -159,7 +159,7 @@ class ElectrumX {
|
||||
* (async () => {
|
||||
* try {
|
||||
* let balance = await bchjs.Electrumx.balance(['bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf', 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v']);
|
||||
* console.log(utxo);
|
||||
* console.log(balance);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
const Bitcoin = require('@psf/bitcoincashjs-lib')
|
||||
const coininfo = require('@psf/coininfo')
|
||||
const bip32utils = require('@psf/bip32-utils')
|
||||
const bip32utils = require('@chris.troutner/bip32-utils')
|
||||
const bchaddrjs = require('bchaddrjs-slp')
|
||||
|
||||
class HDNode {
|
||||
@@ -34,7 +34,9 @@ class HDNode {
|
||||
*/
|
||||
fromSeed (rootSeedBuffer, network = 'mainnet') {
|
||||
let bitcoincash
|
||||
if (network === 'bitcoincash' || network === 'mainnet') { bitcoincash = coininfo.bitcoincash.main } else bitcoincash = coininfo.bitcoincash.test
|
||||
if (network === 'bitcoincash' || network === 'mainnet') {
|
||||
bitcoincash = coininfo.bitcoincash.main
|
||||
} else bitcoincash = coininfo.bitcoincash.test
|
||||
|
||||
const bitcoincashBitcoinJSLib = bitcoincash.toBitcoinJS()
|
||||
return Bitcoin.HDNode.fromSeedBuffer(
|
||||
|
||||
+5
-5
@@ -58,7 +58,7 @@ class Price {
|
||||
* let current = await bchjs.Price.getUsd();
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* console.error(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
@@ -94,7 +94,7 @@ class Price {
|
||||
* let current = await bchjs.Price.rates();
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* console.error(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
@@ -137,7 +137,7 @@ class Price {
|
||||
* let current = await bchjs.Price.getBchaUsd();
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* console.error(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
@@ -175,7 +175,7 @@ class Price {
|
||||
* let current = await bchjs.Price.getXecUsd();
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* console.error(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
@@ -210,7 +210,7 @@ class Price {
|
||||
* let current = await bchjs.Price.getBchUsd();
|
||||
* console.log(current);
|
||||
* } catch(err) {
|
||||
* console.err(err)
|
||||
* console.error(err)
|
||||
* }
|
||||
*})()
|
||||
*
|
||||
|
||||
+2
-2
@@ -432,7 +432,7 @@ class Nft1 {
|
||||
* @apiExample Example usage:
|
||||
*
|
||||
* const groupId = '68cd33ecd909068fbea318ae5ff1d6207cf754e53b191327d6d73b6916424c0a'
|
||||
* const children = await bchjs.SLP.Nft1.listNFTGroupChildren(groupId)
|
||||
* const children = await bchjs.SLP.NFT1.listNFTGroupChildren(groupId)
|
||||
*
|
||||
* children = {
|
||||
* "nftChildren": [
|
||||
@@ -471,7 +471,7 @@ class Nft1 {
|
||||
* @apiExample Example usage:
|
||||
*
|
||||
* const tokenId = '45a30085691d6ea586e3ec2aa9122e9b0e0d6c3c1fd357decccc15d8efde48a9'
|
||||
* const group = await bchjs.SLP.Nft1.parentNFTGroup(tokenId)
|
||||
* const group = await bchjs.SLP.NFT1.parentNFTGroup(tokenId)
|
||||
*
|
||||
* group = {
|
||||
* "nftGroup": {
|
||||
|
||||
+325
-2
@@ -2,15 +2,18 @@
|
||||
High-level functions for working with Transactions
|
||||
*/
|
||||
|
||||
const BigNumber = require('bignumber.js')
|
||||
|
||||
const RawTransaction = require('./raw-transactions')
|
||||
const SlpUtils = require('./slp/utils')
|
||||
const BigNumber = require('bignumber.js')
|
||||
const Blockchain = require('./blockchain')
|
||||
|
||||
class Transaction {
|
||||
constructor (config) {
|
||||
// Encapsulate dependencies
|
||||
this.slpUtils = new SlpUtils(config)
|
||||
this.rawTransaction = new RawTransaction(config)
|
||||
this.blockchain = new Blockchain(config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,10 @@ class Transaction {
|
||||
* }
|
||||
* })()
|
||||
*/
|
||||
|
||||
// CT 10/31/21: TODO: this function should be refactored to use get2(), but
|
||||
// add waterfall validation of the TX and its inputs.
|
||||
|
||||
async get (txid) {
|
||||
try {
|
||||
if (typeof txid !== 'string') {
|
||||
@@ -102,6 +109,7 @@ class Transaction {
|
||||
// Loop through each input and retrieve the token data.
|
||||
for (let i = 0; i < txDetails.vin.length; i++) {
|
||||
const thisVin = txDetails.vin[i]
|
||||
// console.log(`thisVin: ${JSON.stringify(thisVin, null, 2)}`)
|
||||
|
||||
try {
|
||||
// If decodeOpReturn() throws an error, then this input is not
|
||||
@@ -112,7 +120,16 @@ class Transaction {
|
||||
// )
|
||||
|
||||
let tokenQty = 0
|
||||
if (inTokenData.txType === 'SEND') {
|
||||
|
||||
// Validate the input. Mark qty as null if not valid.
|
||||
const vinIsValid = await this.slpUtils.waterfallValidateTxid(
|
||||
thisVin.txid
|
||||
)
|
||||
|
||||
if (!vinIsValid) {
|
||||
// If the input is not a valid, then set qty as null.
|
||||
tokenQty = null
|
||||
} else if (inTokenData.txType === 'SEND') {
|
||||
// Get the appropriate vout token amount. This may throw an error,
|
||||
// which means this Vin is not actually a token UTXO, it was just
|
||||
// associated with a previous token TX.
|
||||
@@ -159,6 +176,9 @@ class Transaction {
|
||||
thisVin.tokenQtyStr = realQty
|
||||
thisVin.tokenQty = parseFloat(realQty)
|
||||
// txDetails.vin[i].tokenQty = tokenQty
|
||||
|
||||
// Add token ID to input
|
||||
thisVin.tokenId = inTokenData.tokenId
|
||||
} else {
|
||||
thisVin.tokenQty = null
|
||||
}
|
||||
@@ -174,6 +194,9 @@ class Transaction {
|
||||
// Finally, validate the SLP TX.
|
||||
// this.slpUtils.waterfallValidateTxid(txid, usrObj)
|
||||
txDetails.isValidSLPTx = await this.slpUtils.waterfallValidateTxid(txid)
|
||||
|
||||
// TODO: Convert the block hash to a block height. Add block height
|
||||
// value to the transaction.
|
||||
} catch (err) {
|
||||
// console.log('Error: ', err)
|
||||
|
||||
@@ -200,6 +223,306 @@ class Transaction {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @api Transaction.get3() get3()
|
||||
* @apiName get3
|
||||
* @apiGroup Transaction
|
||||
* @apiDescription
|
||||
* Returns an object of transaction data, including addresses for input UTXOs.
|
||||
* If it is a SLP token transaction, the token information for inputs and
|
||||
* outputs will also be included.
|
||||
*
|
||||
* This is an API heavy call. This function will only work with a single txid.
|
||||
* It does not yet support an array of TXIDs.
|
||||
*
|
||||
* This is the same as get(), except it omits DAG validation of the TXID.
|
||||
*
|
||||
* @apiExample Example usage:
|
||||
* (async () => {
|
||||
* try {
|
||||
* let txData = await bchjs.Transaction.get2("0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098");
|
||||
* console.log(txData);
|
||||
* } catch(error) {
|
||||
* console.error(error)
|
||||
* }
|
||||
* })()
|
||||
*/
|
||||
async get3 (txid) {
|
||||
try {
|
||||
if (typeof txid !== 'string') {
|
||||
throw new Error(
|
||||
'Input to Transaction.get() must be a string containing a TXID.'
|
||||
)
|
||||
}
|
||||
|
||||
// Get TX data
|
||||
const txDetails = await this.rawTransaction.getTxData(txid)
|
||||
// console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
|
||||
|
||||
// Get the block height the transaction was mined in.
|
||||
const blockHeader = await this.blockchain.getBlockHeader(
|
||||
txDetails.blockhash
|
||||
)
|
||||
txDetails.blockheight = blockHeader.height
|
||||
// console.log(`blockHeader: ${JSON.stringify(blockHeader, null, 2)}`)
|
||||
|
||||
// Set default as not an SLP tx
|
||||
txDetails.isSlpTx = false
|
||||
|
||||
// Get Token Data
|
||||
const txTokenData = await this.getTokenInfo(txid)
|
||||
// console.log(`txTokenData: ${JSON.stringify(txTokenData, null, 2)}`)
|
||||
|
||||
// If not a token, return the tx data. Processing is complete.
|
||||
if (!txTokenData) return txDetails
|
||||
|
||||
// Mark TX as an SLP tx. This does not mean it's valid, it just means
|
||||
// the OP_RETURN passes a basic check.
|
||||
txDetails.isSlpTx = true
|
||||
|
||||
// Get Genesis data
|
||||
const genesisData = await this.getTokenInfo(txTokenData.tokenId)
|
||||
// console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`)
|
||||
|
||||
// Add token information to the tx details object.
|
||||
txDetails.tokenTxType = txTokenData.txType
|
||||
txDetails.tokenId = txTokenData.tokenId
|
||||
txDetails.tokenTicker = genesisData.ticker
|
||||
txDetails.tokenName = genesisData.name
|
||||
txDetails.tokenDecimals = genesisData.decimals
|
||||
txDetails.tokenUri = genesisData.documentUri
|
||||
txDetails.tokenDocHash = genesisData.documentHash
|
||||
// console.log(`txDetails before processing input and outputs: ${JSON.stringify(txDetails, null, 2)}`)
|
||||
|
||||
// Process TX Outputs
|
||||
// Add the token quantity to each output.
|
||||
// 'i' starts at 1, because vout[0] is the OP_RETURN
|
||||
for (let i = 0; i < txDetails.vout.length; i++) {
|
||||
const thisVout = txDetails.vout[i]
|
||||
if (txTokenData.txType === 'SEND') {
|
||||
// console.log(
|
||||
// `output txTokenData: ${JSON.stringify(txTokenData, null, 2)}`
|
||||
// )
|
||||
|
||||
// First output is OP_RETURN, so tokenQty is null.
|
||||
if (i === 0) {
|
||||
thisVout.tokenQty = null
|
||||
thisVout.tokenQtyStr = null
|
||||
continue
|
||||
}
|
||||
|
||||
// Non SLP outputs.
|
||||
if (i > txTokenData.amounts.length) {
|
||||
thisVout.tokenQty = null
|
||||
thisVout.tokenQtyStr = null
|
||||
continue
|
||||
}
|
||||
|
||||
const rawQty = txTokenData.amounts[i - 1]
|
||||
|
||||
// Calculate the real quantity using a BigNumber, then convert it to a
|
||||
// floating point number.
|
||||
let realQty = new BigNumber(rawQty).dividedBy(
|
||||
10 ** parseInt(txDetails.tokenDecimals)
|
||||
)
|
||||
realQty = realQty.toString()
|
||||
// realQty = parseFloat(realQty)
|
||||
|
||||
txDetails.vout[i].tokenQtyStr = realQty
|
||||
txDetails.vout[i].tokenQty = parseFloat(realQty)
|
||||
|
||||
// console.log(
|
||||
// `thisVout ${i}: ${JSON.stringify(txDetails.vout[i], null, 2)}`
|
||||
// )
|
||||
} else if (
|
||||
txTokenData.txType === 'GENESIS' ||
|
||||
txTokenData.txType === 'MINT'
|
||||
) {
|
||||
// console.log(
|
||||
// `output txTokenData: ${JSON.stringify(txTokenData, null, 2)}`
|
||||
// )
|
||||
|
||||
let tokenQty = 0 // Default value
|
||||
|
||||
// Only vout[1] of a Genesis or Mint transaction represents the tokens.
|
||||
// Any other outputs in that transaction are normal BCH UTXOs.
|
||||
if (i === 1) {
|
||||
tokenQty = txTokenData.qty
|
||||
// console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`)
|
||||
|
||||
// Calculate the real quantity using a BigNumber, then convert it to a
|
||||
// floating point number.
|
||||
let realQty = new BigNumber(tokenQty).dividedBy(
|
||||
10 ** parseInt(txDetails.tokenDecimals)
|
||||
)
|
||||
realQty = realQty.toString()
|
||||
// realQty = parseFloat(realQty)
|
||||
|
||||
thisVout.tokenQtyStr = realQty
|
||||
thisVout.tokenQty = parseFloat(realQty)
|
||||
// console.log(`thisVout[${i}]: ${JSON.stringify(thisVout, null, 2)}`)
|
||||
} else if (i === txTokenData.mintBatonVout) {
|
||||
// Optional Mint baton
|
||||
thisVout.tokenQtyStr = '0'
|
||||
thisVout.tokenQty = 0
|
||||
thisVout.isMintBaton = true
|
||||
} else {
|
||||
thisVout.tokenQtyStr = '0'
|
||||
thisVout.tokenQty = 0
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unknown SLP TX type for TX')
|
||||
}
|
||||
}
|
||||
|
||||
// Process TX inputs
|
||||
for (let i = 0; i < txDetails.vin.length; i++) {
|
||||
const thisVin = txDetails.vin[i]
|
||||
// console.log(`thisVin[${i}]: ${JSON.stringify(thisVin, null, 2)}`)
|
||||
|
||||
const vinTokenData = await this.getTokenInfo(thisVin.txid)
|
||||
// console.log(
|
||||
// `vinTokenData ${i}: ${JSON.stringify(vinTokenData, null, 2)}`
|
||||
// )
|
||||
|
||||
// Corner case: Ensure the token ID is the same.
|
||||
const vinTokenIdIsTheSame = vinTokenData.tokenId === txDetails.tokenId
|
||||
|
||||
// If the input is not a token input, or if the tokenID is not the same,
|
||||
// then mark the token output as null.
|
||||
if (!vinTokenData || !vinTokenIdIsTheSame) {
|
||||
thisVin.tokenQty = 0
|
||||
thisVin.tokenQtyStr = '0'
|
||||
thisVin.tokenId = null
|
||||
continue
|
||||
}
|
||||
|
||||
if (vinTokenData.txType === 'SEND') {
|
||||
// console.log(
|
||||
// `SEND vinTokenData ${i}: ${JSON.stringify(vinTokenData, null, 2)}`
|
||||
// )
|
||||
|
||||
const tokenQty = vinTokenData.amounts[thisVin.vout - 1]
|
||||
// console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`)
|
||||
|
||||
// Calculate the real quantity using a BigNumber, then convert it to a
|
||||
// floating point number.
|
||||
let realQty = new BigNumber(tokenQty).dividedBy(
|
||||
10 ** parseInt(txDetails.tokenDecimals)
|
||||
)
|
||||
realQty = realQty.toString()
|
||||
// realQty = parseFloat(realQty)
|
||||
|
||||
thisVin.tokenQtyStr = realQty
|
||||
thisVin.tokenQty = parseFloat(realQty)
|
||||
thisVin.tokenId = vinTokenData.tokenId
|
||||
} else if (vinTokenData.txType === 'MINT') {
|
||||
// console.log(
|
||||
// `MINT vinTokenData ${i}: ${JSON.stringify(vinTokenData, null, 2)}`
|
||||
// )
|
||||
|
||||
let tokenQty = 0 // Default value
|
||||
|
||||
// Only vout[1] of a Genesis transaction represents the tokens.
|
||||
// Any other outputs in that transaction are normal BCH UTXOs.
|
||||
if (thisVin.vout === 1) {
|
||||
tokenQty = vinTokenData.qty
|
||||
// console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`)
|
||||
|
||||
// Calculate the real quantity using a BigNumber, then convert it to a
|
||||
// floating point number.
|
||||
let realQty = new BigNumber(tokenQty).dividedBy(
|
||||
10 ** parseInt(txDetails.tokenDecimals)
|
||||
)
|
||||
realQty = realQty.toString()
|
||||
// realQty = parseFloat(realQty)
|
||||
|
||||
thisVin.tokenQtyStr = realQty
|
||||
thisVin.tokenQty = parseFloat(realQty)
|
||||
thisVin.tokenId = vinTokenData.tokenId
|
||||
} else if (thisVin.vout === vinTokenData.mintBatonVout) {
|
||||
// Optional Mint baton
|
||||
thisVin.tokenQtyStr = '0'
|
||||
thisVin.tokenQty = 0
|
||||
thisVin.tokenId = vinTokenData.tokenId
|
||||
thisVin.isMintBaton = true
|
||||
} else {
|
||||
thisVin.tokenQtyStr = '0'
|
||||
thisVin.tokenQty = 0
|
||||
thisVin.tokenId = null
|
||||
}
|
||||
} else if (vinTokenData.txType === 'GENESIS') {
|
||||
// console.log(
|
||||
// `GENESIS vinTokenData ${i}: ${JSON.stringify(
|
||||
// vinTokenData,
|
||||
// null,
|
||||
// 2
|
||||
// )}`
|
||||
// )
|
||||
|
||||
let tokenQty = 0 // Default value
|
||||
|
||||
// Only vout[1] of a Genesis transaction represents the tokens.
|
||||
// Any other outputs in that transaction are normal BCH UTXOs.
|
||||
if (thisVin.vout === 1) {
|
||||
tokenQty = vinTokenData.qty
|
||||
// console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`)
|
||||
|
||||
// Calculate the real quantity using a BigNumber, then convert it to a
|
||||
// floating point number.
|
||||
let realQty = new BigNumber(tokenQty).dividedBy(
|
||||
10 ** parseInt(txDetails.tokenDecimals)
|
||||
)
|
||||
realQty = realQty.toString()
|
||||
// realQty = parseFloat(realQty)
|
||||
|
||||
thisVin.tokenQtyStr = realQty
|
||||
thisVin.tokenQty = parseFloat(realQty)
|
||||
thisVin.tokenId = vinTokenData.tokenId
|
||||
} else if (thisVin.vout === vinTokenData.mintBatonVout) {
|
||||
// Optional Mint baton
|
||||
thisVin.tokenQtyStr = '0'
|
||||
thisVin.tokenQty = 0
|
||||
thisVin.tokenId = vinTokenData.tokenId
|
||||
thisVin.isMintBaton = true
|
||||
} else {
|
||||
thisVin.tokenQtyStr = '0'
|
||||
thisVin.tokenQty = 0
|
||||
thisVin.tokenId = null
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
`Unknown vinTokenData: ${JSON.stringify(vinTokenData, null, 2)}`
|
||||
)
|
||||
throw new Error('Unknown token type in input')
|
||||
}
|
||||
}
|
||||
|
||||
return txDetails
|
||||
} catch (err) {
|
||||
console.error('Error in get3()')
|
||||
|
||||
// This case handles rate limit errors.
|
||||
if (err.response && err.response.data && err.response.data.error) {
|
||||
throw new Error(err.response.data.error)
|
||||
}
|
||||
|
||||
if (err.error) throw new Error(err.error)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// A wrapper for decodeOpReturn(). Returns false if txid is not an SLP tx.
|
||||
// Returns the token data if the txid is an SLP tx.
|
||||
async getTokenInfo (txid) {
|
||||
try {
|
||||
const tokenData = await this.slpUtils.decodeOpReturn(txid)
|
||||
return tokenData
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Transaction
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
const chai = require('chai')
|
||||
const assert = chai.assert
|
||||
const BCHJS = require('../../src/bch-js')
|
||||
const BCHJS = require('../../../../src/bch-js')
|
||||
const bchjs = new BCHJS()
|
||||
|
||||
// Inspect utility used for debugging.
|
||||
@@ -81,7 +81,8 @@ describe('#util', () => {
|
||||
|
||||
it('should throw error on array size rate limit', async () => {
|
||||
try {
|
||||
const dataMock = 'bitcoincash:qp4k8fjtgunhdr7yq30ha4peuwupzan2vcnwrmpy0z'
|
||||
const dataMock =
|
||||
'bitcoincash:qp4k8fjtgunhdr7yq30ha4peuwupzan2vcnwrmpy0z'
|
||||
const data = []
|
||||
for (let i = 0; i < 25; i++) data.push(dataMock)
|
||||
|
||||
@@ -56,5 +56,26 @@ describe('#Transaction', () => {
|
||||
assert.property(result, 'isValidSLPTx')
|
||||
assert.equal(result.isValidSLPTx, true)
|
||||
})
|
||||
|
||||
// it('should get problematic transaction', async () => {
|
||||
// const txid = 'a55515de32577e296c512840bcaabed5823bb773fb4f8fd8e5197cc96cbc54d1'
|
||||
//
|
||||
// const result = await bchjs.Transaction.get(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
// })
|
||||
|
||||
// TX a19f2f395a8b0e15b6202944c56834367d128f1e3630486a4756de53424a46fe has
|
||||
// an input TXID (bd84bc1dd5ecd976165892306992401272f6bedeb37d7b2cdbf74fc4a55967a6)
|
||||
// that is also a valid SLP tx, but is unrelated. Both TXs pass DAG validation,
|
||||
// but for separate tokens.
|
||||
it('should get problematic transaction', async () => {
|
||||
const txid = 'a19f2f395a8b0e15b6202944c56834367d128f1e3630486a4756de53424a46fe'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// The token ID should equal the txid for this Vin.
|
||||
assert.equal(result.vin[2].txid, result.vin[2].tokenId)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -277,8 +277,10 @@ const mintTestInputTx = {
|
||||
txid: '938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8',
|
||||
vout: 1,
|
||||
scriptSig: {
|
||||
asm: '3045022100e3d5f9a48f9aa1cf7e9ed1992e0281e7300b734ba0e4bd5bb9265b2be60bd71002200ccde53ce7ea9da9df3e834f234f3bea65c2e58c96f8436f93333fd8946a1db2[ALL|FORKID] 02056220984cc2cf5261a27d4f66d31c9ef601a688ca1a5ab81e55b6f0d311be74',
|
||||
hex: '483045022100e3d5f9a48f9aa1cf7e9ed1992e0281e7300b734ba0e4bd5bb9265b2be60bd71002200ccde53ce7ea9da9df3e834f234f3bea65c2e58c96f8436f93333fd8946a1db2412102056220984cc2cf5261a27d4f66d31c9ef601a688ca1a5ab81e55b6f0d311be74'
|
||||
asm:
|
||||
'3045022100e3d5f9a48f9aa1cf7e9ed1992e0281e7300b734ba0e4bd5bb9265b2be60bd71002200ccde53ce7ea9da9df3e834f234f3bea65c2e58c96f8436f93333fd8946a1db2[ALL|FORKID] 02056220984cc2cf5261a27d4f66d31c9ef601a688ca1a5ab81e55b6f0d311be74',
|
||||
hex:
|
||||
'483045022100e3d5f9a48f9aa1cf7e9ed1992e0281e7300b734ba0e4bd5bb9265b2be60bd71002200ccde53ce7ea9da9df3e834f234f3bea65c2e58c96f8436f93333fd8946a1db2412102056220984cc2cf5261a27d4f66d31c9ef601a688ca1a5ab81e55b6f0d311be74'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qpaf9wltgmpjlg2vxwwu7zdw5y4z7m277ckxn8cufl',
|
||||
@@ -290,8 +292,10 @@ const mintTestInputTx = {
|
||||
txid: 'ee9d3cf5153599c134147e3fac9844c68e216843f4452a1ce15a29452af6db34',
|
||||
vout: 1,
|
||||
scriptSig: {
|
||||
asm: '3045022100bb90d52be9b568f643fdb1a302e9f063be27a9f914e2a6b192cbabf2cbdeaf9302203c275fc8d1b82390bc1726390d361c5266056bddd54dec23efa207c79eacea4a[ALL|FORKID] 024146cfcd0c02e99d6451dc48ad0f97114aeda18fe55c52a10bfc0490f314e6a2',
|
||||
hex: '483045022100bb90d52be9b568f643fdb1a302e9f063be27a9f914e2a6b192cbabf2cbdeaf9302203c275fc8d1b82390bc1726390d361c5266056bddd54dec23efa207c79eacea4a4121024146cfcd0c02e99d6451dc48ad0f97114aeda18fe55c52a10bfc0490f314e6a2'
|
||||
asm:
|
||||
'3045022100bb90d52be9b568f643fdb1a302e9f063be27a9f914e2a6b192cbabf2cbdeaf9302203c275fc8d1b82390bc1726390d361c5266056bddd54dec23efa207c79eacea4a[ALL|FORKID] 024146cfcd0c02e99d6451dc48ad0f97114aeda18fe55c52a10bfc0490f314e6a2',
|
||||
hex:
|
||||
'483045022100bb90d52be9b568f643fdb1a302e9f063be27a9f914e2a6b192cbabf2cbdeaf9302203c275fc8d1b82390bc1726390d361c5266056bddd54dec23efa207c79eacea4a4121024146cfcd0c02e99d6451dc48ad0f97114aeda18fe55c52a10bfc0490f314e6a2'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qqf89zzwd0fqc3npkks997r5l7dpfjf9kgx2rqu500',
|
||||
@@ -303,8 +307,10 @@ const mintTestInputTx = {
|
||||
txid: 'ee9d3cf5153599c134147e3fac9844c68e216843f4452a1ce15a29452af6db34',
|
||||
vout: 3,
|
||||
scriptSig: {
|
||||
asm: '3044022029ab770c249f467b40bb90410429f6d657f9be299baa19a6838d04d972436b450220143660297e8e836bc16d317649fad8c310bdadb4fb61d4e9f6ba11203abe5dae[ALL|FORKID] 02eed4ac9dda3405d9b1ccbbf09f8056f3e7c615924274bd5643238b543d0a1d56',
|
||||
hex: '473044022029ab770c249f467b40bb90410429f6d657f9be299baa19a6838d04d972436b450220143660297e8e836bc16d317649fad8c310bdadb4fb61d4e9f6ba11203abe5dae412102eed4ac9dda3405d9b1ccbbf09f8056f3e7c615924274bd5643238b543d0a1d56'
|
||||
asm:
|
||||
'3044022029ab770c249f467b40bb90410429f6d657f9be299baa19a6838d04d972436b450220143660297e8e836bc16d317649fad8c310bdadb4fb61d4e9f6ba11203abe5dae[ALL|FORKID] 02eed4ac9dda3405d9b1ccbbf09f8056f3e7c615924274bd5643238b543d0a1d56',
|
||||
hex:
|
||||
'473044022029ab770c249f467b40bb90410429f6d657f9be299baa19a6838d04d972436b450220143660297e8e836bc16d317649fad8c310bdadb4fb61d4e9f6ba11203abe5dae412102eed4ac9dda3405d9b1ccbbf09f8056f3e7c615924274bd5643238b543d0a1d56'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qqt30r33k0jx3sxe34tmupaujpaljnglmvqgrrfp2x',
|
||||
@@ -318,8 +324,10 @@ const mintTestInputTx = {
|
||||
value: 0,
|
||||
n: 0,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_RETURN 5262419 1 1145980243 938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8 0000000103907f11',
|
||||
hex: '6a04534c500001010453454e4420938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8080000000103907f11',
|
||||
asm:
|
||||
'OP_RETURN 5262419 1 1145980243 938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8 0000000103907f11',
|
||||
hex:
|
||||
'6a04534c500001010453454e4420938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8080000000103907f11',
|
||||
type: 'nulldata'
|
||||
},
|
||||
tokenQty: null
|
||||
@@ -328,13 +336,12 @@ const mintTestInputTx = {
|
||||
value: 0.00000546,
|
||||
n: 1,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_DUP OP_HASH160 059775ff94f65c04e8a6847e74eb9809d8cd779b OP_EQUALVERIFY OP_CHECKSIG',
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 059775ff94f65c04e8a6847e74eb9809d8cd779b OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a914059775ff94f65c04e8a6847e74eb9809d8cd779b88ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: [
|
||||
'bitcoincash:qqzewa0ljnm9cp8g56z8ua8tnqya3nthnvhv5hpu8y'
|
||||
]
|
||||
addresses: ['bitcoincash:qqzewa0ljnm9cp8g56z8ua8tnqya3nthnvhv5hpu8y']
|
||||
},
|
||||
tokenQtyStr: '43547.68657',
|
||||
tokenQty: 43547.68657
|
||||
@@ -343,18 +350,18 @@ const mintTestInputTx = {
|
||||
value: 0.00054808,
|
||||
n: 2,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_DUP OP_HASH160 0e330dc9009e1e07831f5a22d4ade8977ab674c8 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 0e330dc9009e1e07831f5a22d4ade8977ab674c8 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a9140e330dc9009e1e07831f5a22d4ade8977ab674c888ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: [
|
||||
'bitcoincash:qq8rxrwfqz0pupurradz949dazth4dn5eqs3mhrucv'
|
||||
]
|
||||
addresses: ['bitcoincash:qq8rxrwfqz0pupurradz949dazth4dn5eqs3mhrucv']
|
||||
},
|
||||
tokenQty: null
|
||||
}
|
||||
],
|
||||
hex: '0100000003f8cda53b43b0ea49991a9bc6c74eb901d2a8b964bc7b8987d76789618ec18c93010000006b483045022100e3d5f9a48f9aa1cf7e9ed1992e0281e7300b734ba0e4bd5bb9265b2be60bd71002200ccde53ce7ea9da9df3e834f234f3bea65c2e58c96f8436f93333fd8946a1db2412102056220984cc2cf5261a27d4f66d31c9ef601a688ca1a5ab81e55b6f0d311be74feffffff34dbf62a45295ae11c2a45f44368218ec64498ac3f7e1434c1993515f53c9dee010000006b483045022100bb90d52be9b568f643fdb1a302e9f063be27a9f914e2a6b192cbabf2cbdeaf9302203c275fc8d1b82390bc1726390d361c5266056bddd54dec23efa207c79eacea4a4121024146cfcd0c02e99d6451dc48ad0f97114aeda18fe55c52a10bfc0490f314e6a2feffffff34dbf62a45295ae11c2a45f44368218ec64498ac3f7e1434c1993515f53c9dee030000006a473044022029ab770c249f467b40bb90410429f6d657f9be299baa19a6838d04d972436b450220143660297e8e836bc16d317649fad8c310bdadb4fb61d4e9f6ba11203abe5dae412102eed4ac9dda3405d9b1ccbbf09f8056f3e7c615924274bd5643238b543d0a1d56feffffff030000000000000000376a04534c500001010453454e4420938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8080000000103907f1122020000000000001976a914059775ff94f65c04e8a6847e74eb9809d8cd779b88ac18d60000000000001976a9140e330dc9009e1e07831f5a22d4ade8977ab674c888ac7d4b0800',
|
||||
hex:
|
||||
'0100000003f8cda53b43b0ea49991a9bc6c74eb901d2a8b964bc7b8987d76789618ec18c93010000006b483045022100e3d5f9a48f9aa1cf7e9ed1992e0281e7300b734ba0e4bd5bb9265b2be60bd71002200ccde53ce7ea9da9df3e834f234f3bea65c2e58c96f8436f93333fd8946a1db2412102056220984cc2cf5261a27d4f66d31c9ef601a688ca1a5ab81e55b6f0d311be74feffffff34dbf62a45295ae11c2a45f44368218ec64498ac3f7e1434c1993515f53c9dee010000006b483045022100bb90d52be9b568f643fdb1a302e9f063be27a9f914e2a6b192cbabf2cbdeaf9302203c275fc8d1b82390bc1726390d361c5266056bddd54dec23efa207c79eacea4a4121024146cfcd0c02e99d6451dc48ad0f97114aeda18fe55c52a10bfc0490f314e6a2feffffff34dbf62a45295ae11c2a45f44368218ec64498ac3f7e1434c1993515f53c9dee030000006a473044022029ab770c249f467b40bb90410429f6d657f9be299baa19a6838d04d972436b450220143660297e8e836bc16d317649fad8c310bdadb4fb61d4e9f6ba11203abe5dae412102eed4ac9dda3405d9b1ccbbf09f8056f3e7c615924274bd5643238b543d0a1d56feffffff030000000000000000376a04534c500001010453454e4420938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8080000000103907f1122020000000000001976a914059775ff94f65c04e8a6847e74eb9809d8cd779b88ac18d60000000000001976a9140e330dc9009e1e07831f5a22d4ade8977ab674c888ac7d4b0800',
|
||||
blockhash: '00000000000000000140f0d813052da59c811a936494a8d8b2d60b215d19e3dc',
|
||||
confirmations: 167007,
|
||||
time: 1534391953,
|
||||
@@ -393,9 +400,7 @@ const mintTestOpReturnData01 = {
|
||||
tokenType: 1,
|
||||
txType: 'SEND',
|
||||
tokenId: '938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8',
|
||||
amounts: [
|
||||
'4354768657'
|
||||
]
|
||||
amounts: ['4354768657']
|
||||
}
|
||||
|
||||
const mintTestOpReturnData02 = {
|
||||
@@ -430,8 +435,10 @@ const sendTestInputTx01 = {
|
||||
txid: 'b36b0c7485ad569b98cc9b9614dc68a5208495f22ec3b00effcf963b135a5215',
|
||||
vout: 1,
|
||||
scriptSig: {
|
||||
asm: '3045022100934ca9732bf6c1b146f09e6198142a79a80788b576c6b94e2052df5bcdc86ad902205ef6205192200ea93f6c97f966b838ee785529b694eb61e576e3452470613847[ALL|FORKID] 02b23484341cf36ec00184e045d54e6ffca97da7a8f8a6fd719cead192132306b1',
|
||||
hex: '483045022100934ca9732bf6c1b146f09e6198142a79a80788b576c6b94e2052df5bcdc86ad902205ef6205192200ea93f6c97f966b838ee785529b694eb61e576e3452470613847412102b23484341cf36ec00184e045d54e6ffca97da7a8f8a6fd719cead192132306b1'
|
||||
asm:
|
||||
'3045022100934ca9732bf6c1b146f09e6198142a79a80788b576c6b94e2052df5bcdc86ad902205ef6205192200ea93f6c97f966b838ee785529b694eb61e576e3452470613847[ALL|FORKID] 02b23484341cf36ec00184e045d54e6ffca97da7a8f8a6fd719cead192132306b1',
|
||||
hex:
|
||||
'483045022100934ca9732bf6c1b146f09e6198142a79a80788b576c6b94e2052df5bcdc86ad902205ef6205192200ea93f6c97f966b838ee785529b694eb61e576e3452470613847412102b23484341cf36ec00184e045d54e6ffca97da7a8f8a6fd719cead192132306b1'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qqxj7p2jatt8h3tcpadyxw8a2mr7myqk2qm57u4rdf',
|
||||
@@ -441,8 +448,10 @@ const sendTestInputTx01 = {
|
||||
txid: 'b36b0c7485ad569b98cc9b9614dc68a5208495f22ec3b00effcf963b135a5215',
|
||||
vout: 3,
|
||||
scriptSig: {
|
||||
asm: '3044022004d4a95658ef140561ae3a936fb01511778a5376a499bcd6f47b64074a6ca4430220273a4bf553ca17c7e10f393582f980e17a6a98ada867633faad9dbcc595dfd23[ALL|FORKID] 0324fe3b895cfa09523e8ec529eb15c681e3a20f96df85175c54a952b68ac018df',
|
||||
hex: '473044022004d4a95658ef140561ae3a936fb01511778a5376a499bcd6f47b64074a6ca4430220273a4bf553ca17c7e10f393582f980e17a6a98ada867633faad9dbcc595dfd2341210324fe3b895cfa09523e8ec529eb15c681e3a20f96df85175c54a952b68ac018df'
|
||||
asm:
|
||||
'3044022004d4a95658ef140561ae3a936fb01511778a5376a499bcd6f47b64074a6ca4430220273a4bf553ca17c7e10f393582f980e17a6a98ada867633faad9dbcc595dfd23[ALL|FORKID] 0324fe3b895cfa09523e8ec529eb15c681e3a20f96df85175c54a952b68ac018df',
|
||||
hex:
|
||||
'473044022004d4a95658ef140561ae3a936fb01511778a5376a499bcd6f47b64074a6ca4430220273a4bf553ca17c7e10f393582f980e17a6a98ada867633faad9dbcc595dfd2341210324fe3b895cfa09523e8ec529eb15c681e3a20f96df85175c54a952b68ac018df'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qrcdncgpnv3s8lekcamv4yekp8sghnk37qtsxdyzla',
|
||||
@@ -452,8 +461,10 @@ const sendTestInputTx01 = {
|
||||
txid: '95d460512143b636bbc5780d8b27b04fca3bfd2f22003ab48da594e2bab9cfc1',
|
||||
vout: 2,
|
||||
scriptSig: {
|
||||
asm: '3044022079f239216f8d806a084221e841227e55d23a1b90aaf5b5ab54d6f865fbeacf8b022053568f10afc00459af083e4c77d0b85229eb8973a1de406aaa699557f05c7fed[ALL|FORKID] 02035f98ff79d6f3a8ec5a2738c103bbb7796e94fcaffdfaae8f5b7a7fae5d93e3',
|
||||
hex: '473044022079f239216f8d806a084221e841227e55d23a1b90aaf5b5ab54d6f865fbeacf8b022053568f10afc00459af083e4c77d0b85229eb8973a1de406aaa699557f05c7fed412102035f98ff79d6f3a8ec5a2738c103bbb7796e94fcaffdfaae8f5b7a7fae5d93e3'
|
||||
asm:
|
||||
'3044022079f239216f8d806a084221e841227e55d23a1b90aaf5b5ab54d6f865fbeacf8b022053568f10afc00459af083e4c77d0b85229eb8973a1de406aaa699557f05c7fed[ALL|FORKID] 02035f98ff79d6f3a8ec5a2738c103bbb7796e94fcaffdfaae8f5b7a7fae5d93e3',
|
||||
hex:
|
||||
'473044022079f239216f8d806a084221e841227e55d23a1b90aaf5b5ab54d6f865fbeacf8b022053568f10afc00459af083e4c77d0b85229eb8973a1de406aaa699557f05c7fed412102035f98ff79d6f3a8ec5a2738c103bbb7796e94fcaffdfaae8f5b7a7fae5d93e3'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qrcukahsm53lsywcdarehh73vqazpdu8zv547nym9g',
|
||||
@@ -465,8 +476,10 @@ const sendTestInputTx01 = {
|
||||
value: 0,
|
||||
n: 0,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_RETURN 5262419 1 1145980243 550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35 00005af3107a4000 004657febe8d8000',
|
||||
hex: '6a04534c500001010453454e4420550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b350800005af3107a400008004657febe8d8000',
|
||||
asm:
|
||||
'OP_RETURN 5262419 1 1145980243 550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35 00005af3107a4000 004657febe8d8000',
|
||||
hex:
|
||||
'6a04534c500001010453454e4420550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b350800005af3107a400008004657febe8d8000',
|
||||
type: 'nulldata'
|
||||
}
|
||||
},
|
||||
@@ -474,43 +487,41 @@ const sendTestInputTx01 = {
|
||||
value: 0.00000546,
|
||||
n: 1,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_DUP OP_HASH160 268dadd7c7becc11782ad3d956342442d8eae92a OP_EQUALVERIFY OP_CHECKSIG',
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 268dadd7c7becc11782ad3d956342442d8eae92a OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a914268dadd7c7becc11782ad3d956342442d8eae92a88ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: [
|
||||
'bitcoincash:qqngmtwhc7lvcytc9tfaj435y3pd36hf9gtdq8nsuu'
|
||||
]
|
||||
addresses: ['bitcoincash:qqngmtwhc7lvcytc9tfaj435y3pd36hf9gtdq8nsuu']
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.00000546,
|
||||
n: 2,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_DUP OP_HASH160 9fb45b370f9ff38a775ee95cabcad7615817924e OP_EQUALVERIFY OP_CHECKSIG',
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 9fb45b370f9ff38a775ee95cabcad7615817924e OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a9149fb45b370f9ff38a775ee95cabcad7615817924e88ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: [
|
||||
'bitcoincash:qz0mgkehp70l8znhtm54e2726as4s9ujfc9s2szctr'
|
||||
]
|
||||
addresses: ['bitcoincash:qz0mgkehp70l8znhtm54e2726as4s9ujfc9s2szctr']
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.00153347,
|
||||
n: 3,
|
||||
scriptPubKey: {
|
||||
asm: 'OP_DUP OP_HASH160 9fb45b370f9ff38a775ee95cabcad7615817924e OP_EQUALVERIFY OP_CHECKSIG',
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 9fb45b370f9ff38a775ee95cabcad7615817924e OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a9149fb45b370f9ff38a775ee95cabcad7615817924e88ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: [
|
||||
'bitcoincash:qz0mgkehp70l8znhtm54e2726as4s9ujfc9s2szctr'
|
||||
]
|
||||
addresses: ['bitcoincash:qz0mgkehp70l8znhtm54e2726as4s9ujfc9s2szctr']
|
||||
}
|
||||
}
|
||||
],
|
||||
hex: '010000000315525a133b96cfff0eb0c32ef2958420a568dc14969bcc989b56ad85740c6bb3010000006b483045022100934ca9732bf6c1b146f09e6198142a79a80788b576c6b94e2052df5bcdc86ad902205ef6205192200ea93f6c97f966b838ee785529b694eb61e576e3452470613847412102b23484341cf36ec00184e045d54e6ffca97da7a8f8a6fd719cead192132306b1feffffff15525a133b96cfff0eb0c32ef2958420a568dc14969bcc989b56ad85740c6bb3030000006a473044022004d4a95658ef140561ae3a936fb01511778a5376a499bcd6f47b64074a6ca4430220273a4bf553ca17c7e10f393582f980e17a6a98ada867633faad9dbcc595dfd2341210324fe3b895cfa09523e8ec529eb15c681e3a20f96df85175c54a952b68ac018dffeffffffc1cfb9bae294a58db43a00222ffd3bca4fb0278b0d78c5bb36b643215160d495020000006a473044022079f239216f8d806a084221e841227e55d23a1b90aaf5b5ab54d6f865fbeacf8b022053568f10afc00459af083e4c77d0b85229eb8973a1de406aaa699557f05c7fed412102035f98ff79d6f3a8ec5a2738c103bbb7796e94fcaffdfaae8f5b7a7fae5d93e3feffffff040000000000000000406a04534c500001010453454e4420550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b350800005af3107a400008004657febe8d800022020000000000001976a914268dadd7c7becc11782ad3d956342442d8eae92a88ac22020000000000001976a9149fb45b370f9ff38a775ee95cabcad7615817924e88ac03570200000000001976a9149fb45b370f9ff38a775ee95cabcad7615817924e88acd44c0800',
|
||||
hex:
|
||||
'010000000315525a133b96cfff0eb0c32ef2958420a568dc14969bcc989b56ad85740c6bb3010000006b483045022100934ca9732bf6c1b146f09e6198142a79a80788b576c6b94e2052df5bcdc86ad902205ef6205192200ea93f6c97f966b838ee785529b694eb61e576e3452470613847412102b23484341cf36ec00184e045d54e6ffca97da7a8f8a6fd719cead192132306b1feffffff15525a133b96cfff0eb0c32ef2958420a568dc14969bcc989b56ad85740c6bb3030000006a473044022004d4a95658ef140561ae3a936fb01511778a5376a499bcd6f47b64074a6ca4430220273a4bf553ca17c7e10f393582f980e17a6a98ada867633faad9dbcc595dfd2341210324fe3b895cfa09523e8ec529eb15c681e3a20f96df85175c54a952b68ac018dffeffffffc1cfb9bae294a58db43a00222ffd3bca4fb0278b0d78c5bb36b643215160d495020000006a473044022079f239216f8d806a084221e841227e55d23a1b90aaf5b5ab54d6f865fbeacf8b022053568f10afc00459af083e4c77d0b85229eb8973a1de406aaa699557f05c7fed412102035f98ff79d6f3a8ec5a2738c103bbb7796e94fcaffdfaae8f5b7a7fae5d93e3feffffff040000000000000000406a04534c500001010453454e4420550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b350800005af3107a400008004657febe8d800022020000000000001976a914268dadd7c7becc11782ad3d956342442d8eae92a88ac22020000000000001976a9149fb45b370f9ff38a775ee95cabcad7615817924e88ac03570200000000001976a9149fb45b370f9ff38a775ee95cabcad7615817924e88acd44c0800',
|
||||
blockhash: '000000000000000001882548bbd9a41bc53a039634f2afa4a12d653434347d04',
|
||||
confirmations: 166670,
|
||||
time: 1534593905,
|
||||
@@ -521,10 +532,7 @@ const sendTestOpReturnData01 = {
|
||||
tokenType: 1,
|
||||
txType: 'SEND',
|
||||
tokenId: '550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35',
|
||||
amounts: [
|
||||
'100000000000000',
|
||||
'19800000000000000'
|
||||
]
|
||||
amounts: ['100000000000000', '19800000000000000']
|
||||
}
|
||||
|
||||
const sendTestOpReturnData02 = {
|
||||
@@ -533,8 +541,10 @@ const sendTestOpReturnData02 = {
|
||||
ticker: 'USDT',
|
||||
name: 'Tether Ltd. US dollar backed tokens',
|
||||
tokenId: '550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35',
|
||||
documentUri: 'https://tether.to/wp-content/uploads/2016/06/TetherWhitePaper.pdf',
|
||||
documentHash: '�DQ�\u001e�3�\u0006p���pM�\u0001\u0017�pW(;\u0003,��wy19\u0016',
|
||||
documentUri:
|
||||
'https://tether.to/wp-content/uploads/2016/06/TetherWhitePaper.pdf',
|
||||
documentHash:
|
||||
'�DQ�\u001e�3�\u0006p���pM�\u0001\u0017�pW(;\u0003,��wy19\u0016',
|
||||
decimals: 8,
|
||||
mintBatonVout: 2,
|
||||
qty: '10000000000000000'
|
||||
@@ -552,10 +562,211 @@ const sendTestOpReturnData04 = {
|
||||
tokenType: 1,
|
||||
txType: 'SEND',
|
||||
tokenId: '550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35',
|
||||
amounts: [
|
||||
'100000000000000',
|
||||
'9900000000000000'
|
||||
]
|
||||
amounts: ['100000000000000', '9900000000000000']
|
||||
}
|
||||
|
||||
const mintTestInputTx02 = {
|
||||
txid: 'ee9d3cf5153599c134147e3fac9844c68e216843f4452a1ce15a29452af6db34',
|
||||
hash: 'ee9d3cf5153599c134147e3fac9844c68e216843f4452a1ce15a29452af6db34',
|
||||
version: 1,
|
||||
size: 473,
|
||||
locktime: 543613,
|
||||
vin: [
|
||||
{
|
||||
txid: '938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8',
|
||||
vout: 3,
|
||||
scriptSig: {
|
||||
asm:
|
||||
'3045022100ac43a871e0f84787001db745e4801b789fd9cd7efa247727ebb5c0c7b66d597302205316328b6501759e9a15ec65202219a433172d153f9f1b68f65f3a63494ba6f0[ALL|FORKID] 0345a5f5dd11c987b346c18c245f0df6d305369984b9b3c7ba465c29875466e374',
|
||||
hex:
|
||||
'483045022100ac43a871e0f84787001db745e4801b789fd9cd7efa247727ebb5c0c7b66d597302205316328b6501759e9a15ec65202219a433172d153f9f1b68f65f3a63494ba6f041210345a5f5dd11c987b346c18c245f0df6d305369984b9b3c7ba465c29875466e374'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qqj0durd4qzdddvl2u6sen8n8h6mljtywugqctt9km',
|
||||
value: 0.00056266
|
||||
},
|
||||
{
|
||||
txid: '938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8',
|
||||
vout: 2,
|
||||
scriptSig: {
|
||||
asm:
|
||||
'304402202ce2d9d63bc6ab7765d267540fd3429bf7a8d1b50e975391fff3a4506289461a02205daf3f761a9b02d141f22136a6fe019062182c9da1b1d3a5245ff745f1236e45[ALL|FORKID] 02c00b05bc633a48e074bc54dd195b19a470ad6252ac8d306c82a2bd729c1c4c69',
|
||||
hex:
|
||||
'47304402202ce2d9d63bc6ab7765d267540fd3429bf7a8d1b50e975391fff3a4506289461a02205daf3f761a9b02d141f22136a6fe019062182c9da1b1d3a5245ff745f1236e45412102c00b05bc633a48e074bc54dd195b19a470ad6252ac8d306c82a2bd729c1c4c69'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qzf72qccdgjrpjpewq8dazlze6jyxzku8q3cauna4t',
|
||||
value: 0.00000546
|
||||
}
|
||||
],
|
||||
vout: [
|
||||
{
|
||||
value: 0,
|
||||
n: 0,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_RETURN 5262419 1 1414416717 938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8 2 000000000003928b',
|
||||
hex:
|
||||
'6a04534c50000101044d494e5420938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8010208000000000003928b',
|
||||
type: 'nulldata'
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.00000546,
|
||||
n: 1,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 1272884e6bd20c4661b5a052f874ff9a14c925b2 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a9141272884e6bd20c4661b5a052f874ff9a14c925b288ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: ['bitcoincash:qqf89zzwd0fqc3npkks997r5l7dpfjf9kgx2rqu500']
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.00000546,
|
||||
n: 2,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 d1eaebf8d1face5bd866e36bd94f43e2ffceef71 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a914d1eaebf8d1face5bd866e36bd94f43e2ffceef7188ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: ['bitcoincash:qrg746lc68avuk7cvm3khk20g030lnh0wy5h2k2fqr']
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.00054848,
|
||||
n: 3,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 17178e31b3e468c0d98d57be07bc907bf94d1fdb OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a91417178e31b3e468c0d98d57be07bc907bf94d1fdb88ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: ['bitcoincash:qqt30r33k0jx3sxe34tmupaujpaljnglmvqgrrfp2x']
|
||||
}
|
||||
}
|
||||
],
|
||||
hex:
|
||||
'0100000002f8cda53b43b0ea49991a9bc6c74eb901d2a8b964bc7b8987d76789618ec18c93030000006b483045022100ac43a871e0f84787001db745e4801b789fd9cd7efa247727ebb5c0c7b66d597302205316328b6501759e9a15ec65202219a433172d153f9f1b68f65f3a63494ba6f041210345a5f5dd11c987b346c18c245f0df6d305369984b9b3c7ba465c29875466e374fefffffff8cda53b43b0ea49991a9bc6c74eb901d2a8b964bc7b8987d76789618ec18c93020000006a47304402202ce2d9d63bc6ab7765d267540fd3429bf7a8d1b50e975391fff3a4506289461a02205daf3f761a9b02d141f22136a6fe019062182c9da1b1d3a5245ff745f1236e45412102c00b05bc633a48e074bc54dd195b19a470ad6252ac8d306c82a2bd729c1c4c69feffffff040000000000000000396a04534c50000101044d494e5420938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8010208000000000003928b22020000000000001976a9141272884e6bd20c4661b5a052f874ff9a14c925b288ac22020000000000001976a914d1eaebf8d1face5bd866e36bd94f43e2ffceef7188ac40d60000000000001976a91417178e31b3e468c0d98d57be07bc907bf94d1fdb88ac7d4b0800',
|
||||
blockhash: '00000000000000000140f0d813052da59c811a936494a8d8b2d60b215d19e3dc',
|
||||
confirmations: 168436,
|
||||
time: 1534391953,
|
||||
blocktime: 1534391953
|
||||
}
|
||||
|
||||
const mintTestOpReturnData04 = {
|
||||
tokenType: 1,
|
||||
txType: 'MINT',
|
||||
tokenId: '938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8',
|
||||
mintBatonVout: 2,
|
||||
qty: '234123'
|
||||
}
|
||||
|
||||
const mintTestOpReturnData05 = {
|
||||
tokenType: 1,
|
||||
txType: 'GENESIS',
|
||||
ticker: 'Bubb2',
|
||||
name: 'the new bubbles!',
|
||||
tokenId: '938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8',
|
||||
documentUri: '',
|
||||
documentHash: '',
|
||||
decimals: 5,
|
||||
mintBatonVout: 2,
|
||||
qty: '4354534534'
|
||||
}
|
||||
|
||||
const genesisTestInputTx02 = {
|
||||
txid: '4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf',
|
||||
hash: '4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf',
|
||||
version: 1,
|
||||
size: 444,
|
||||
locktime: 571211,
|
||||
vin: [
|
||||
{
|
||||
txid: 'f3e056874846b6f491a1ccac3da81a3411c61d8466835446a52efa68c0d11804',
|
||||
vout: 0,
|
||||
scriptSig: {
|
||||
asm:
|
||||
'3044022022fb67bd9b35810db3fa04da4014cc93063c5ed15e8febeca09d32c03397068502206fbb86498919ca8a9be6940c904c944cd923691391a4a7d92e0c841605d46b2e[ALL|FORKID] 03fbe2c56094dc336f6244eac2e45d3d25a8e97059f2cc7de31cbf179e73dcc9bf',
|
||||
hex:
|
||||
'473044022022fb67bd9b35810db3fa04da4014cc93063c5ed15e8febeca09d32c03397068502206fbb86498919ca8a9be6940c904c944cd923691391a4a7d92e0c841605d46b2e412103fbe2c56094dc336f6244eac2e45d3d25a8e97059f2cc7de31cbf179e73dcc9bf'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qz6rcxjw34yuy5fngu7fngnyy55t0v802cmsmjvsp2',
|
||||
value: 0.00001111
|
||||
},
|
||||
{
|
||||
txid: '87bf0efc1630f5179b73496f9f885b141cb4c8366432a91ba678298432b197ea',
|
||||
vout: 0,
|
||||
scriptSig: {
|
||||
asm:
|
||||
'3045022100d5fbab461c19c7b56245287eb15510c86872ceb405ede7322f5266efa6cc32ea022074b557bcef9a129fb31cb2e7c2ada9fe51d5cf924ae55d1d2a29368ca1f15ef2[ALL|FORKID] 03fbe2c56094dc336f6244eac2e45d3d25a8e97059f2cc7de31cbf179e73dcc9bf',
|
||||
hex:
|
||||
'483045022100d5fbab461c19c7b56245287eb15510c86872ceb405ede7322f5266efa6cc32ea022074b557bcef9a129fb31cb2e7c2ada9fe51d5cf924ae55d1d2a29368ca1f15ef2412103fbe2c56094dc336f6244eac2e45d3d25a8e97059f2cc7de31cbf179e73dcc9bf'
|
||||
},
|
||||
sequence: 4294967294,
|
||||
address: 'bitcoincash:qz6rcxjw34yuy5fngu7fngnyy55t0v802cmsmjvsp2',
|
||||
value: 0.007
|
||||
}
|
||||
],
|
||||
vout: [
|
||||
{
|
||||
value: 0,
|
||||
n: 0,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_RETURN 5262419 1 47454e45534953 5350494345 5370696365 7370696365736c7040676d61696c2e636f6d 0 8 0 016345785d8a0000',
|
||||
hex:
|
||||
'6a04534c500001010747454e45534953055350494345055370696365127370696365736c7040676d61696c2e636f6d4c0001084c0008016345785d8a0000',
|
||||
type: 'nulldata'
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.00000546,
|
||||
n: 1,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 70e5c384ae563b4fd6cfc5f7f8df43ea427d9e10 OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a91470e5c384ae563b4fd6cfc5f7f8df43ea427d9e1088ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: ['bitcoincash:qpcwtsuy4etrkn7kelzl07xlg04yylv7zqru2cqwvm']
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 0.0070012,
|
||||
n: 2,
|
||||
scriptPubKey: {
|
||||
asm:
|
||||
'OP_DUP OP_HASH160 df305a87d98cd64e1bee825d2167a16445ecdfdd OP_EQUALVERIFY OP_CHECKSIG',
|
||||
hex: '76a914df305a87d98cd64e1bee825d2167a16445ecdfdd88ac',
|
||||
reqSigs: 1,
|
||||
type: 'pubkeyhash',
|
||||
addresses: ['bitcoincash:qr0nqk58mxxdvnsma6p96gt859jytmxlm5t0v7de4q']
|
||||
}
|
||||
}
|
||||
],
|
||||
hex:
|
||||
'01000000020418d1c068fa2ea546548366841dc611341aa83daccca191f4b646488756e0f3000000006a473044022022fb67bd9b35810db3fa04da4014cc93063c5ed15e8febeca09d32c03397068502206fbb86498919ca8a9be6940c904c944cd923691391a4a7d92e0c841605d46b2e412103fbe2c56094dc336f6244eac2e45d3d25a8e97059f2cc7de31cbf179e73dcc9bffeffffffea97b132842978a61ba9326436c8b41c145b889f6f49739b17f53016fc0ebf87000000006b483045022100d5fbab461c19c7b56245287eb15510c86872ceb405ede7322f5266efa6cc32ea022074b557bcef9a129fb31cb2e7c2ada9fe51d5cf924ae55d1d2a29368ca1f15ef2412103fbe2c56094dc336f6244eac2e45d3d25a8e97059f2cc7de31cbf179e73dcc9bffeffffff0300000000000000003e6a04534c500001010747454e45534953055350494345055370696365127370696365736c7040676d61696c2e636f6d4c0001084c0008016345785d8a000022020000000000001976a91470e5c384ae563b4fd6cfc5f7f8df43ea427d9e1088acd8ae0a00000000001976a914df305a87d98cd64e1bee825d2167a16445ecdfdd88ac4bb70800',
|
||||
blockhash: '000000000000000002278c188c52b536d4ed84a1970d8ff59043e082cef7748a',
|
||||
confirmations: 141226,
|
||||
time: 1551042875,
|
||||
blocktime: 1551042875
|
||||
}
|
||||
|
||||
const genesisTestOpReturn03 = {
|
||||
tokenType: 1,
|
||||
txType: 'GENESIS',
|
||||
ticker: 'SPICE',
|
||||
name: 'Spice',
|
||||
tokenId: '4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf',
|
||||
documentUri: 'spiceslp@gmail.com',
|
||||
documentHash: '',
|
||||
decimals: 8,
|
||||
mintBatonVout: 0,
|
||||
qty: '100000000000000000'
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -575,5 +786,10 @@ module.exports = {
|
||||
sendTestOpReturnData01,
|
||||
sendTestOpReturnData02,
|
||||
sendTestOpReturnData03,
|
||||
sendTestOpReturnData04
|
||||
sendTestOpReturnData04,
|
||||
mintTestInputTx02,
|
||||
mintTestOpReturnData04,
|
||||
mintTestOpReturnData05,
|
||||
genesisTestInputTx02,
|
||||
genesisTestOpReturn03
|
||||
}
|
||||
|
||||
@@ -5,15 +5,21 @@
|
||||
// Public npm libraries
|
||||
const assert = require('chai').assert
|
||||
const sinon = require('sinon')
|
||||
const cloneDeep = require('lodash.clonedeep')
|
||||
|
||||
const BCHJS = require('../../src/bch-js')
|
||||
const bchjs = new BCHJS()
|
||||
|
||||
const mockData = require('./fixtures/transaction-mock.js')
|
||||
const mockDataLib = require('./fixtures/transaction-mock.js')
|
||||
|
||||
describe('#TransactionLib', () => {
|
||||
let sandbox
|
||||
beforeEach(() => (sandbox = sinon.createSandbox()))
|
||||
let sandbox, mockData
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox()
|
||||
|
||||
mockData = cloneDeep(mockDataLib)
|
||||
})
|
||||
afterEach(() => sandbox.restore())
|
||||
|
||||
describe('#get', () => {
|
||||
@@ -265,4 +271,438 @@ describe('#TransactionLib', () => {
|
||||
assert.equal(result.vin[2].tokenQty, 99000000)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#get3', () => {
|
||||
it('should throw an error if txid is not specified', async () => {
|
||||
try {
|
||||
await bchjs.Transaction.get3()
|
||||
|
||||
assert.fail('Unexpected code path!')
|
||||
} catch (err) {
|
||||
assert.include(
|
||||
err.message,
|
||||
'Input to Transaction.get() must be a string containing a TXID.'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('should get details about a non-SLP transaction', async () => {
|
||||
const txid =
|
||||
'2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7'
|
||||
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.nonSlpTxDetails)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 602405 })
|
||||
sandbox.stub(bchjs.Transaction, 'getTokenInfo').resolves(false)
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[0].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert that added properties exist.
|
||||
assert.property(result.vin[0], 'address')
|
||||
assert.property(result.vin[0], 'value')
|
||||
|
||||
// Assert blockheight is added
|
||||
assert.equal(result.blockheight, 602405)
|
||||
assert.equal(result.isSlpTx, false)
|
||||
})
|
||||
|
||||
it('should get details about a SLP SEND tx with SEND input', async () => {
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.slpTxDetails)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 603424 })
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.slpUtils, 'decodeOpReturn')
|
||||
.onCall(0)
|
||||
.resolves(mockData.mockOpReturnData01)
|
||||
.onCall(1)
|
||||
.resolves(mockData.mockOpReturnData02)
|
||||
.onCall(2)
|
||||
.resolves(mockData.mockOpReturnData03)
|
||||
.onCall(3)
|
||||
.rejects(new Error('No OP_RETURN'))
|
||||
|
||||
const txid =
|
||||
'266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[1].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert outputs have expected properties
|
||||
assert.equal(result.vout[0].tokenQty, null)
|
||||
assert.equal(result.vout[0].tokenQtyStr, null)
|
||||
assert.equal(result.vout[1].tokenQty, 1)
|
||||
assert.equal(result.vout[1].tokenQtyStr, '1')
|
||||
assert.equal(result.vout[2].tokenQty, 998833)
|
||||
assert.equal(result.vout[2].tokenQtyStr, '998833')
|
||||
assert.equal(result.vout[3].tokenQty, null)
|
||||
assert.equal(result.vout[3].tokenQtyStr, null)
|
||||
|
||||
// Assert that inputs have expected properties
|
||||
assert.equal(result.vin[0].tokenQtyStr, '998834')
|
||||
assert.equal(result.vin[0].tokenQty, 998834)
|
||||
assert.equal(
|
||||
result.vin[0].tokenId,
|
||||
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
|
||||
)
|
||||
assert.equal(result.vin[1].tokenQtyStr, '0')
|
||||
assert.equal(result.vin[1].tokenQty, 0)
|
||||
assert.equal(result.vin[1].tokenId, null)
|
||||
|
||||
// Assert blockheight is added
|
||||
assert.equal(result.blockheight, 603424)
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
|
||||
it('should catch and throw error on network error', async () => {
|
||||
try {
|
||||
const txid =
|
||||
'2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7'
|
||||
|
||||
// Force an error
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.rejects(new Error('test error'))
|
||||
|
||||
await bchjs.Transaction.get3(txid)
|
||||
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (err) {
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
// This test case was created in response to a bug. When the input TX
|
||||
// was a Genesis SLP transaction, the inputs of the transaction were not
|
||||
// being hydrated properly.
|
||||
it('should get details about a SLP SEND tx with GENSIS input', async () => {
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.genesisTestInputTx)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 543409 })
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.slpUtils, 'decodeOpReturn')
|
||||
.onCall(0)
|
||||
.resolves(mockData.genesisTestOpReturnData01)
|
||||
.onCall(1)
|
||||
.resolves(mockData.genesisTestOpReturnData02)
|
||||
.onCall(2)
|
||||
.resolves(mockData.genesisTestOpReturnData02)
|
||||
.onCall(3)
|
||||
.resolves(mockData.genesisTestOpReturnData02)
|
||||
|
||||
const txid =
|
||||
'874306bda204d3a5dd15e03ea5732cccdca4c33a52df35162cdd64e30ea7f04e'
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[1].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert outputs have expected properties and values
|
||||
assert.equal(result.vout[0].tokenQty, null)
|
||||
assert.equal(result.vout[0].tokenQtyStr, null)
|
||||
assert.equal(result.vout[1].tokenQty, 5000000)
|
||||
assert.equal(result.vout[1].tokenQtyStr, '5000000')
|
||||
assert.equal(result.vout[2].tokenQty, 5000000)
|
||||
assert.equal(result.vout[2].tokenQtyStr, '5000000')
|
||||
assert.equal(result.vout[3].tokenQty, null)
|
||||
assert.equal(result.vout[3].tokenQtyStr, null)
|
||||
|
||||
// Assert inputs have expected properties and values
|
||||
assert.equal(result.vin[0].tokenQty, 10000000)
|
||||
assert.equal(result.vin[0].tokenQtyStr, '10000000')
|
||||
assert.equal(
|
||||
result.vin[0].tokenId,
|
||||
'323a1e35ae0b356316093d20f2d9fbc995d19314b5c0148b78dc8d9c0dab9d35'
|
||||
)
|
||||
assert.equal(result.vin[1].tokenQty, 0)
|
||||
assert.equal(result.vin[1].tokenQtyStr, '0')
|
||||
assert.equal(result.vin[1].tokenId, null)
|
||||
|
||||
// Assert blockheight is added
|
||||
assert.equal(result.blockheight, 543409)
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
|
||||
it('should get details about a SLP SEND tx with MINT (and GENESIS) input', async () => {
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.mintTestInputTx)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 543614 })
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.slpUtils, 'decodeOpReturn')
|
||||
.onCall(0)
|
||||
.resolves(mockData.mintTestOpReturnData01)
|
||||
.onCall(1)
|
||||
.resolves(mockData.mintTestOpReturnData02)
|
||||
.onCall(2)
|
||||
.resolves(mockData.mintTestOpReturnData02)
|
||||
.onCall(3)
|
||||
.resolves(mockData.mintTestOpReturnData03)
|
||||
.onCall(4)
|
||||
.resolves(mockData.mintTestOpReturnData03)
|
||||
|
||||
const txid =
|
||||
'4640a734063ea79fa587a3cac38a70a2f6f3db0011e23514024185982110d0fa'
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[1].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert expected output properties and values exist.
|
||||
assert.equal(result.vout[0].tokenQty, null)
|
||||
assert.equal(result.vout[1].tokenQty, 43547.68657)
|
||||
assert.equal(result.vout[1].tokenQtyStr, '43547.68657')
|
||||
assert.equal(result.vout[2].tokenQty, null)
|
||||
|
||||
// Assert expected input properties and values exist.
|
||||
assert.equal(result.vin[0].tokenQty, 43545.34534)
|
||||
assert.equal(result.vin[0].tokenQtyStr, '43545.34534')
|
||||
assert.equal(
|
||||
result.vin[0].tokenId,
|
||||
'938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8'
|
||||
)
|
||||
assert.equal(result.vin[1].tokenQty, 2.34123)
|
||||
assert.equal(result.vin[1].tokenQtyStr, '2.34123')
|
||||
assert.equal(
|
||||
result.vin[1].tokenId,
|
||||
'938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8'
|
||||
)
|
||||
assert.equal(result.vin[2].tokenQty, 0)
|
||||
assert.equal(result.vin[2].tokenQtyStr, '0')
|
||||
assert.equal(result.vin[2].tokenId, null)
|
||||
|
||||
// Assert blockheight is added
|
||||
assert.equal(result.blockheight, 543614)
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
|
||||
// This test case was generated from the problematic transaction that
|
||||
// used inputs in a 'non-standard' way.
|
||||
it('should get details about a SLP SEND tx with MINT (and SEND) input', async () => {
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.sendTestInputTx01)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 543957 })
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.slpUtils, 'decodeOpReturn')
|
||||
.onCall(0)
|
||||
.resolves(mockData.sendTestOpReturnData01)
|
||||
.onCall(1)
|
||||
.resolves(mockData.sendTestOpReturnData02)
|
||||
.onCall(2)
|
||||
.resolves(mockData.sendTestOpReturnData03)
|
||||
.onCall(3)
|
||||
.resolves(mockData.sendTestOpReturnData03)
|
||||
.onCall(4)
|
||||
.resolves(mockData.sendTestOpReturnData04)
|
||||
|
||||
const txid =
|
||||
'6bc111fbf5b118021d68355ca19a0e77fa358dd931f284b2550f79a51ab4792a'
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[1].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert the outputs have expected properties and values.
|
||||
assert.equal(result.vout[0].tokenQty, null)
|
||||
assert.equal(result.vout[1].tokenQty, 1000000)
|
||||
assert.equal(result.vout[1].tokenQtyStr, '1000000')
|
||||
assert.equal(result.vout[2].tokenQty, 198000000)
|
||||
assert.equal(result.vout[2].tokenQtyStr, '198000000')
|
||||
assert.equal(result.vout[3].tokenQty, null)
|
||||
|
||||
// Assert the inputs have expected properties and values.
|
||||
assert.equal(result.vin[0].tokenQty, 100000000)
|
||||
assert.equal(result.vin[0].tokenQtyStr, '100000000')
|
||||
assert.equal(
|
||||
result.vin[0].tokenId,
|
||||
'550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35'
|
||||
)
|
||||
assert.equal(result.vin[1].tokenQty, 0)
|
||||
assert.equal(result.vin[1].tokenQtyStr, 0)
|
||||
assert.equal(result.vin[1].tokenId, null)
|
||||
assert.equal(result.vin[2].tokenQty, 99000000)
|
||||
assert.equal(result.vin[2].tokenQtyStr, '99000000')
|
||||
assert.equal(
|
||||
result.vin[2].tokenId,
|
||||
'550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35'
|
||||
)
|
||||
|
||||
// Assert blockheight is added
|
||||
assert.equal(result.blockheight, 543957)
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
|
||||
// This was a problematic TX
|
||||
it('should process MINT TX with GENESIS input', async () => {
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.mintTestInputTx02)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 543614 })
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.slpUtils, 'decodeOpReturn')
|
||||
.onCall(0)
|
||||
.resolves(mockData.mintTestOpReturnData04)
|
||||
.onCall(1)
|
||||
.resolves(mockData.mintTestOpReturnData05)
|
||||
.onCall(2)
|
||||
.resolves(mockData.mintTestOpReturnData05)
|
||||
.onCall(3)
|
||||
.resolves(mockData.mintTestOpReturnData05)
|
||||
.onCall(4)
|
||||
.resolves(mockData.mintTestOpReturnData05)
|
||||
.onCall(5)
|
||||
.resolves(mockData.mintTestOpReturnData05)
|
||||
|
||||
const txid =
|
||||
'ee9d3cf5153599c134147e3fac9844c68e216843f4452a1ce15a29452af6db34'
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[1].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert outputs have expected properties and values
|
||||
assert.equal(result.vout[0].tokenQty, 0)
|
||||
assert.equal(result.vout[0].tokenQty, '0')
|
||||
assert.equal(result.vout[1].tokenQty, 2.34123)
|
||||
assert.equal(result.vout[1].tokenQty, '2.34123')
|
||||
assert.equal(result.vout[2].tokenQty, 0)
|
||||
assert.equal(result.vout[2].tokenQty, '0')
|
||||
assert.equal(result.vout[2].isMintBaton, true)
|
||||
assert.equal(result.vout[3].tokenQty, 0)
|
||||
assert.equal(result.vout[3].tokenQty, '0')
|
||||
|
||||
// Assert inputs have expected properties and values
|
||||
assert.equal(result.vin[0].tokenQty, 0)
|
||||
assert.equal(result.vin[0].tokenQtyStr, '0')
|
||||
assert.equal(result.vin[0].tokenId, null)
|
||||
assert.equal(result.vin[1].tokenQty, 0)
|
||||
assert.equal(result.vin[1].tokenQtyStr, '0')
|
||||
assert.equal(
|
||||
result.vin[1].tokenId,
|
||||
'938cc18e618967d787897bbc64b9a8d201b94ec7c69b1a9949eab0433ba5cdf8'
|
||||
)
|
||||
assert.equal(result.vin[1].isMintBaton, true)
|
||||
|
||||
// Assert added TX data exists.
|
||||
assert.equal(result.blockheight, 543614)
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
|
||||
// It should process a GENESIS tx
|
||||
it('should process a GENESIS tx', async () => {
|
||||
// Mock dependencies
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.genesisTestInputTx02)
|
||||
sandbox
|
||||
.stub(bchjs.Transaction.blockchain, 'getBlockHeader')
|
||||
.resolves({ height: 571212 })
|
||||
sandbox
|
||||
.stub(bchjs.Transaction, 'getTokenInfo')
|
||||
.onCall(0)
|
||||
.resolves(mockData.genesisTestOpReturn03)
|
||||
.onCall(1)
|
||||
.resolves(mockData.genesisTestOpReturn03)
|
||||
.onCall(2)
|
||||
.resolves(false)
|
||||
.onCall(3)
|
||||
.resolves(false)
|
||||
.onCall(4)
|
||||
.resolves(false)
|
||||
|
||||
const txid =
|
||||
'4de69e374a8ed21cbddd47f2338cc0f479dc58daa2bbe11cd604ca488eca0ddf'
|
||||
|
||||
const result = await bchjs.Transaction.get3(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
assert.property(result, 'txid')
|
||||
assert.property(result, 'vin')
|
||||
assert.property(result, 'vout')
|
||||
assert.property(result.vout[0], 'value')
|
||||
assert.property(result.vout[1].scriptPubKey, 'addresses')
|
||||
|
||||
// Assert output have expected properties and values
|
||||
assert.equal(result.vout[0].tokenQty, 0)
|
||||
assert.equal(result.vout[0].tokenQtyStr, '0')
|
||||
assert.equal(result.vout[0].isMintBaton, true)
|
||||
assert.equal(result.vout[1].tokenQty, 1000000000)
|
||||
assert.equal(result.vout[1].tokenQtyStr, '1000000000')
|
||||
assert.equal(result.vout[2].tokenQty, 0)
|
||||
assert.equal(result.vout[2].tokenQtyStr, '0')
|
||||
|
||||
// Assert input have expected properties and values
|
||||
assert.equal(result.vin[0].tokenQty, 0)
|
||||
assert.equal(result.vin[0].tokenQtyStr, '0')
|
||||
assert.equal(result.vin[0].tokenId, null)
|
||||
assert.equal(result.vin[1].tokenQty, 0)
|
||||
assert.equal(result.vin[1].tokenQtyStr, '0')
|
||||
assert.equal(result.vin[1].tokenId, null)
|
||||
|
||||
// Assert added TX data exists.
|
||||
assert.equal(result.blockheight, 571212)
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user