UNPKG

qos-qweb

Version:
193 lines 17.4 kB
import bech32 from 'bech32'; import { Int64BE } from 'int64-buffer'; import { Codec } from 'js-amino'; import nacl from 'tweetnacl'; import { accMul, Int64ToBuffer, stringToBuffer } from '.'; import { qosDecimal } from '../types/common'; import { MsgMultiSend, PubKeyEd25519, QSC, Receiver, Sender, Signature, StdTx } from '../types/tx'; export function getOriginAddress(address) { const addrDecode = bech32.decode(address); const fromwords = bech32.fromWords(addrDecode.words); return fromwords; } export function signTxMsg(oMsg) { const msg = makeTxSignMsg(oMsg); const signatureData = nacl.sign.detached(Buffer.from(msg.signedMsg), oMsg.account.keypair.secretKey); const codec = registerCodec(); const pubKey = new PubKeyEd25519([...oMsg.account.keypair.publicKey]); const sig = new Signature(pubKey, [...signatureData], oMsg.nonce.toString()); const sendMultiMsg = new MsgMultiSend(msg.senders, msg.receivers); const stdtx = new StdTx(sendMultiMsg, [sig], oMsg.chainid, oMsg.maxGas.toString()); // const jsonTx = codec.marshalJson(stdtx) // logger.debug('stdtx: ') // logger.info(jsonTx) // logger.debug('marshalBinary: ') const binary = codec.marshalBinary(stdtx); // logger.debug(binary.toString()) // const decodedDataTx = new StdTx(); // codec.unMarshalBinary(binary, decodedDataTx) // logger.debug('unMb StdTx: ') // logger.info(decodedDataTx.JsObject()) return binary; } function makeTxSignMsg({ account, tx, chainid, maxGas, nonce }) { let arrMsg = []; // push buffer of orginaddress const fromAddress = getOriginAddress(account.address); arrMsg = arrMsg.concat(fromAddress); const allData = composeData(tx); // concat buffer of qosAmount arrMsg = arrMsg.concat([...stringToBuffer(allData.qosAmount.toString())]); // concat buffer of qscAmount const qscArray = []; const qscArr = []; for (const qsc of allData.qscAmountArr) { qscArray.push(`${qsc.amount}${qsc.coinName}`); qscArr.push(new QSC(qsc.coinName, qsc.amount.toString())); } // compose qsc string , e.g. 2qsca,3qscb const qscString = qscArray.join(','); arrMsg = arrMsg.concat([...stringToBuffer(qscString)]); arrMsg = arrMsg.concat([...allData.arrReceiver]); const chaidBufferArray = [...stringToBuffer(chainid)]; arrMsg = arrMsg.concat(chaidBufferArray); arrMsg = arrMsg.concat([...Int64ToBuffer(maxGas)]); arrMsg = arrMsg.concat([...Int64ToBuffer(nonce)]); arrMsg = arrMsg.concat(chaidBufferArray); const senders = [ new Sender(fromAddress, allData.qosAmount.toString(), qscArr) ]; const receivers = allData.receivers; return { signedMsg: arrMsg, senders, receivers }; } function registerCodec() { const codec = new Codec(); codec.registerConcrete(new StdTx(), 'qbase/txs/stdtx', {}); codec.registerConcrete(new MsgMultiSend(), 'transfer/txs/TxTransfer', {}); codec.registerConcrete(new PubKeyEd25519(), 'tendermint/PubKeyEd25519', {}); return codec; } function composeData(tx) { const coinNameArr = getQscCoinNames(tx); if (Array.isArray(tx)) { return txIsArrayForComposeData(tx, coinNameArr); } return txForComposeData(tx, coinNameArr); } function txIsArrayForComposeData(tx, coinNameArr) { let qosAmount = 0; const qscAmountArr = []; // 添加 receiver 代签名 byte[] let arrReceiver = []; const receivers = []; for (const item of tx) { item.qos = accMul(item.qos, qosDecimal); qosAmount += item.qos; const toAddress = getOriginAddress(item.to); arrReceiver = arrReceiver.concat(toAddress); arrReceiver = arrReceiver.concat([...stringToBuffer(item.qos.toString())]); const qscArr = []; const cqscAmountArr = []; if (item.qscs && item.qscs.length > 0) { for (const coinName of coinNameArr) { const cqsc = item.qscs .filter(x => x.coin_name.toLowerCase() === coinName) .reduce((pre, current) => { return { coin_name: pre.coin_name, amount: pre.amount + current.amount }; }); cqsc.amount = accMul(cqsc.amount, qosDecimal); cqscAmountArr.push(`${cqsc.amount}${coinName}`); qscArr.push(new QSC(coinName, cqsc.amount.toString())); const index = qscAmountArr.findIndex(x => x.coinName === coinName); if (index > -1) { qscAmountArr[index].amount += cqsc.amount; } else { qscAmountArr.push({ coinName, amount: cqsc.amount }); } } arrReceiver = arrReceiver.concat([ ...stringToBuffer(cqscAmountArr.join(',')) ]); } receivers.push(new Receiver(toAddress, item.qos.toString(), qscArr)); } return { qosAmount: new Int64BE(qosAmount), qscAmountArr, arrReceiver, receivers }; } function txForComposeData(tx, coinNameArr) { let qosAmount = 0; const qscAmountArr = []; // 添加 receiver 代签名 byte[] let arrReceiver = []; const qscArr = []; qosAmount = accMul(tx.qos, qosDecimal); const toAddress = getOriginAddress(tx.to); arrReceiver = arrReceiver.concat(toAddress); arrReceiver = arrReceiver.concat([...stringToBuffer(tx.qos.toString())]); const cqscAmountArr = []; if (tx.qscs && tx.qscs.length > 0) { for (const coinName of coinNameArr) { const cqsc = tx.qscs .filter(x => x.coin_name.toLowerCase() === coinName) .reduce((pre, current) => { return { coin_name: pre.coin_name, amount: pre.amount + current.amount }; }); cqsc.amount = accMul(cqsc.amount, qosDecimal); cqscAmountArr.push(`${cqsc.amount}${coinName}`); qscAmountArr.push({ coinName, amount: cqsc.amount }); qscArr.push(new QSC(coinName, cqsc.amount.toString())); } arrReceiver = arrReceiver.concat([ ...stringToBuffer(cqscAmountArr.join(',')) ]); } const receivers = [new Receiver(toAddress, tx.qos.toString(), qscAmountArr)]; return { qosAmount: new Int64BE(qosAmount), qscAmountArr, arrReceiver, receivers }; } /** * 去重并获取所有QSC的CoinName数组,如['QSC'] * @param tx 交易体 */ function getQscCoinNames(tx) { const qscSet = new Set(); if (Array.isArray(tx)) { for (const item of tx) { if (item.qscs && item.qscs.length > 0) { for (const qsc of item.qscs) { qscSet.add(qsc.coin_name.toLowerCase()); } } } } else { if (tx.qscs && tx.qscs.length > 0) { for (const qsc of tx.qscs) { qscSet.add(qsc.coin_name.toLowerCase()); } } } return [...qscSet]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHhTaWduRGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3V0aWxzL1R4U2lnbkRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNqQyxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sR0FBRyxDQUFDO0FBRTFELE9BQU8sRUFBVyxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsWUFBWSxFQUNaLGFBQWEsRUFDYixHQUFHLEVBQ0gsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsS0FBSyxFQUNOLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUFlO0lBQzlDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUMsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsSUFNekI7SUFDQyxNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQ3RDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQy9CLENBQUM7SUFFRixNQUFNLEtBQUss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