fix(Transaction.get): Using BigNumber for better tokenqty calc

This commit is contained in:
Chris Troutner
2021-09-22 17:33:27 -07:00
parent 6f4cc0f439
commit dc7d3a9339
2 changed files with 40 additions and 15 deletions
+39 -14
View File
@@ -4,6 +4,7 @@
const RawTransaction = require('./raw-transactions') const RawTransaction = require('./raw-transactions')
const SlpUtils = require('./slp/utils') const SlpUtils = require('./slp/utils')
const BigNumber = require('bignumber.js')
class Transaction { class Transaction {
constructor (config) { constructor (config) {
@@ -43,7 +44,7 @@ class Transaction {
} }
const txDetails = await this.rawTransaction.getTxData(txid) const txDetails = await this.rawTransaction.getTxData(txid)
console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`) // console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
// Setup default SLP properties. // Setup default SLP properties.
txDetails.isValidSLPTx = false txDetails.isValidSLPTx = false
@@ -53,7 +54,7 @@ class Transaction {
let outTokenData let outTokenData
try { try {
outTokenData = await this.slpUtils.decodeOpReturn(txid) outTokenData = await this.slpUtils.decodeOpReturn(txid)
console.log(`outTokenData: ${JSON.stringify(outTokenData, null, 2)}`) // console.log(`outTokenData: ${JSON.stringify(outTokenData, null, 2)}`)
// Get Genesis data for this token. // Get Genesis data for this token.
const genesisData = await this.slpUtils.decodeOpReturn( const genesisData = await this.slpUtils.decodeOpReturn(
@@ -61,7 +62,7 @@ class Transaction {
// decodeOpReturnCache // decodeOpReturnCache
// usrObj // pass user data when making an internal call. // usrObj // pass user data when making an internal call.
) )
console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`) // console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`)
// Add token information to the tx details object. // Add token information to the tx details object.
txDetails.tokenTxType = outTokenData.txType txDetails.tokenTxType = outTokenData.txType
@@ -75,9 +76,18 @@ class Transaction {
// Add the token quantity to each output. // Add the token quantity to each output.
for (let i = 0; i < outTokenData.amounts.length; i++) { for (let i = 0; i < outTokenData.amounts.length; i++) {
const rawQty = outTokenData.amounts[i] const rawQty = outTokenData.amounts[i]
const realQty = Number(rawQty) / Math.pow(10, txDetails.tokenDecimals) // const realQty = Number(rawQty) / Math.pow(10, txDetails.tokenDecimals)
txDetails.vout[i + 1].tokenQty = realQty // 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 + 1].tokenQtyStr = realQty
txDetails.vout[i + 1].tokenQty = parseFloat(realQty)
} }
// Add tokenQty = null to any outputs that don't have a value. // Add tokenQty = null to any outputs that don't have a value.
@@ -97,9 +107,9 @@ class Transaction {
// If decodeOpReturn() throws an error, then this input is not // If decodeOpReturn() throws an error, then this input is not
// from an SLP transaction and can be ignored. // from an SLP transaction and can be ignored.
const inTokenData = await this.slpUtils.decodeOpReturn(thisVin.txid) const inTokenData = await this.slpUtils.decodeOpReturn(thisVin.txid)
console.log( // console.log(
`vin[${i}] tokenData: ${JSON.stringify(inTokenData, null, 2)}` // `vin[${i}] tokenData: ${JSON.stringify(inTokenData, null, 2)}`
) // )
let tokenQty = 0 let tokenQty = 0
if (inTokenData.txType === 'SEND') { if (inTokenData.txType === 'SEND') {
@@ -107,25 +117,40 @@ class Transaction {
// which means this Vin is not actually a token UTXO, it was just // which means this Vin is not actually a token UTXO, it was just
// associated with a previous token TX. // associated with a previous token TX.
tokenQty = inTokenData.amounts[thisVin.vout - 1] tokenQty = inTokenData.amounts[thisVin.vout - 1]
console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`) // console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`)
//
} else if (inTokenData.txType === 'GENESIS') { } else if (inTokenData.txType === 'GENESIS') {
// Only vout[1] of a Genesis transaction represents the tokens. // Only vout[1] of a Genesis transaction represents the tokens.
// Any other outputs in that transaction are normal BCH UTXOs. // Any other outputs in that transaction are normal BCH UTXOs.
if (thisVin.vout === 1) { if (thisVin.vout === 1) {
tokenQty = inTokenData.qty tokenQty = inTokenData.qty
console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`) // console.log(`tokenQty: ${JSON.stringify(tokenQty, null, 2)}`)
} }
//
} else { } else {
console.log('Unexpected code path. Is this a MINT transaction?') console.log(
'Unexpected code path in Transaction.get(). Is this a MINT transaction?'
)
console.log(inTokenData) console.log(inTokenData)
throw new Error('Unexpected code path') throw new Error('Unexpected code path')
} }
if (tokenQty) { if (tokenQty) {
const realQty = // const realQty =
Number(tokenQty) / Math.pow(10, txDetails.tokenDecimals) // Number(tokenQty) / Math.pow(10, txDetails.tokenDecimals)
thisVin.tokenQty = realQty // 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)
// txDetails.vin[i].tokenQty = tokenQty // txDetails.vin[i].tokenQty = tokenQty
} else { } else {
thisVin.tokenQty = null thisVin.tokenQty = null
+1 -1
View File
@@ -142,7 +142,7 @@ describe('#TransactionLib', () => {
'874306bda204d3a5dd15e03ea5732cccdca4c33a52df35162cdd64e30ea7f04e' '874306bda204d3a5dd15e03ea5732cccdca4c33a52df35162cdd64e30ea7f04e'
const result = await bchjs.Transaction.get(txid) const result = await bchjs.Transaction.get(txid)
console.log(`result: ${JSON.stringify(result, null, 2)}`) // console.log(`result: ${JSON.stringify(result, null, 2)}`)
// Assert that there are stanardized properties. // Assert that there are stanardized properties.
assert.property(result, 'txid') assert.property(result, 'txid')