SHARE
TWEET

Untitled

a guest Sep 24th, 2019 82 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { BITBOX } from "bitbox-sdk";
  2. let bitbox = new BITBOX()
  3.  
  4. const claimOpreturnVersion      = Buffer.from('0abcde1d', 'hex');
  5. const transactOpreturnVersion   = Buffer.from('0abcde1e', 'hex');
  6. const rateOpreturnVersion       = Buffer.from('0abcde1f', 'hex');
  7.  
  8.  
  9. function createWallet(seed) {
  10.     seed = seed || bitbox.Mnemonic.fromEntropy(bitbox.Crypto.randomBytes(32));
  11.     let seedBuffer = bitbox.Mnemonic.toSeed(seed)
  12.     return bitbox.HDNode.fromSeed(seedBuffer);
  13. }
  14.  
  15. async function getAnUtxo(anAddress, minAmount) {
  16.     minAmount = minAmount || 1000;
  17.     let utxos = await bitbox.Address.utxo(anAddress);
  18.     let utxo = utxos.utxos.find(u => u.satoshis >= 1000);
  19.     if (utxo)
  20.         return utxo;
  21.     else
  22.         throw "No suitable utxo for transaction";
  23. }
  24.  
  25. async function claimAddress(wallet, network) {
  26.     network = network || 'mainnet';
  27.     var transactionBuilder = new bitbox.TransactionBuilder(network);
  28.     let redeemScript;
  29.  
  30.     let cashAddress = bitbox.HDNode.toCashAddress(wallet);
  31.     let address160  = bitbox.Address.cashToHash160(cashAddress);
  32.     let messageBuffer = Buffer.from(address160, "hex");
  33.     let signature   = bitbox.BitcoinCash.signMessageWithPrivKey(
  34.         wallet.keyPair.toWIF(),
  35.         address160
  36.     );
  37.     let contentBuffer =  Buffer.concat([
  38.         claimOpreturnVersion,
  39.         messageBuffer,
  40.         Buffer.from(signature, 'base64')
  41.     ]);
  42.  
  43.     console.log(signature);
  44.     let opReturn = bitbox.Script.encode([
  45.         bitbox.Script.opcodes.OP_RETURN,
  46.         contentBuffer,
  47.        ]);
  48.  
  49.     console.log(opReturn);
  50.     var byteCount = bitbox.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 });
  51.     byteCount += contentBuffer.length;
  52.     byteCount += signature.length;
  53.     byteCount += 9 // some spare bytes for OP_RETURN etc.
  54.    
  55.     var utxo = await getAnUtxo(cashAddress);
  56.     transactionBuilder.addInput(utxo.txid, utxo.vout);
  57.     transactionBuilder.addOutput(cashAddress, utxo.satoshis - byteCount);
  58.     transactionBuilder.addOutput(opReturn, 0);
  59.     transactionBuilder.setLockTime(0);
  60.     transactionBuilder.sign(0, wallet.keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, utxo.satoshis, transactionBuilder.signatureAlgorithms.SCHNORR)
  61.  
  62.     var tx = transactionBuilder.build();
  63.     var hex = tx.toHex();
  64.     console.log("Sending tx from "+ utxo.txid +" with op_return "+ claimOpreturnVersion + messageBuffer.toString() + signature + " contentBuffer length "+ contentBuffer.length)
  65.     let txid = await bitbox.RawTransactions.sendRawTransaction(hex);
  66.     console.log(txid);
  67.     return txid;
  68. }
  69.  
  70. async function getClaimDetails(transactionId) {
  71.     var transaction = await bitbox.Transaction.details(transactionId);
  72.     var opReturnOutput = transaction.vout.find(function(out) {return out.scriptPubKey.addresses === undefined;});
  73.     var message = opReturnOutput.scriptPubKey.asm;
  74.  
  75.     let result = {};
  76.     result.version     = message.substring(10, 18);
  77.     result.versionValid= result.version === '0abcde1d';
  78.     result.address160  = message.substring(18, 58);
  79.     result.address     = bitbox.Address.hash160ToCash(result.address160);
  80.     result.signature   = Buffer.from(message.substring(58), 'hex').toString('base64');
  81.  
  82.     result.signatureValid = bitbox.BitcoinCash.verifyMessage(
  83.         result.address,
  84.         result.signature,
  85.         result.address160
  86.     );
  87.  
  88.     return result;
  89. }
  90.  
  91. async function transact(fromWallet, toWallet, amount, network) {
  92.     network = network || 'mainnet';
  93.     var transactionBuilder = new bitbox.TransactionBuilder(network);
  94.     let redeemScript;
  95.  
  96.     let cashAddress1 = bitbox.HDNode.toCashAddress(fromWallet);
  97.     let cashAddress2 = bitbox.HDNode.toCashAddress(toWallet);
  98.  
  99.     let utxo = await getAnUtxo(cashAddress1, amount);
  100.     var byteCount = bitbox.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 2 });
  101.  
  102.     let originalAmount = utxo.satoshis;
  103.     let amountToSend   = amount;
  104.     let fee            = byteCount;
  105.  
  106.     transactionBuilder.addInput(utxo.txid, utxo.vout);
  107.     transactionBuilder.addOutput(cashAddress2, amountToSend);
  108.     transactionBuilder.addOutput(cashAddress1, originalAmount - amountToSend - fee);
  109.  
  110.     transactionBuilder.setLockTime(0);
  111.     transactionBuilder.sign(0, fromWallet.keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount, transactionBuilder.signatureAlgorithms.SCHNORR)
  112.     var tx = transactionBuilder.build();
  113.     var hex = tx.toHex();
  114.     return await bitbox.RawTransactions.sendRawTransaction(hex);
  115. }
  116.  
  117. function createMessage(reviewee, reviewer, transactionId, rating) {
  118.     var reviewee160 = Buffer.from(bitbox.Address.cashToHash160(reviewee), 'hex');
  119.     var reviewer160 = Buffer.from(bitbox.Address.cashToHash160(reviewer), 'hex');
  120.     var ratedTx     = Buffer.from(transactionId, 'hex');
  121.     var rating      = Buffer.from(rating.toString(), 'hex');
  122.     var message     = Buffer.concat([reviewee160, reviewer160, ratedTx, rating]);
  123.     return message;
  124. }
  125.  
  126. async function rateTransaction(reviewee, reviewer, transactionId, rating, wallet, network) {
  127.     network = network || 'mainnet';
  128.     var transactionBuilder = new bitbox.TransactionBuilder(network)
  129.     let redeemScript;
  130.     let message = createMessage(reviewee, reviewer, transactionId, rating);
  131.     var signature = bitbox.BitcoinCash.signMessageWithPrivKey(wallet.keyPair.toWIF(), message.toString());
  132.     var contentBuffer = Buffer.concat([
  133.         rateOpreturnVersion,
  134.         message,
  135.         Buffer.from(signature, 'base64')
  136.     ]);
  137.  
  138.     var opReturn = bitbox.Script.encode([
  139.         bitbox.Script.opcodes.OP_RETURN,
  140.         contentBuffer
  141.     ]);
  142.     console.log(opReturn);
  143.     let utxo = await getAnUtxo(reviewer);
  144.  
  145.     var byteCount = bitbox.BitcoinCash.getByteCount({ P2PKH: 1 }, { P2PKH: 1 });
  146.     byteCount += contentBuffer.length;
  147.     byteCount += 9 // some spare bytes for OP_RETURN, version etc.
  148.     var originalAmount = utxo.satoshis;
  149.     transactionBuilder.addInput(utxo.txid, utxo.vout);
  150.     transactionBuilder.addOutput(reviewer, originalAmount - byteCount);
  151.     transactionBuilder.addOutput(opReturn, 0);
  152.     transactionBuilder.setLockTime(0);
  153.     transactionBuilder.sign(0, wallet.keyPair, redeemScript, transactionBuilder.hashTypes.SIGHASH_ALL, originalAmount, transactionBuilder.signatureAlgorithms.SCHNORR)
  154.     var tx = transactionBuilder.build();
  155.     var hex = tx.toHex();
  156.     console.log("Sending tx from "+ utxo.txid +" with op_return "+ rateOpreturnVersion + message + signature + " contentBuffer length "+ contentBuffer.length)
  157.     return await bitbox.RawTransactions.sendRawTransaction(hex);
  158. }
  159.  
  160. async function checkRatedTransactionConditions(details) {
  161.     var ratedTransaction = await bitbox.Transaction.details(details.ratedTransaction);
  162.     console.log(ratedTransaction);
  163.  
  164.     if (ratedTransaction.vin[0].cashAddress === details.reviewer) {
  165.         console.log("from matched with reviewer")
  166.         return ratedTransaction.vout.some(out => {
  167.             return out.scriptPubKey.cashAddrs.some(addr => addr === details.reviewee)
  168.         });
  169.  
  170.     } else if (ratedTransaction.vin[0].cashAddress === details.reviewee) {
  171.         console.log("from matched with reviewee")
  172.  
  173.         return ratedTransaction.vout.some(out => {
  174.             return out.scriptPubKey.cashAddrs.some(addr => addr === details.reviewer)
  175.         });
  176.  
  177.     } else {
  178.         console.log("from matched none")
  179.         return false; //
  180.     }
  181. }
  182.  
  183. async function getRatingDetails(transactionId) {
  184.     var transaction = await bitbox.Transaction.details(transactionId);
  185.     var opReturnOutput = transaction.vout.find(function(out) {return out.scriptPubKey.addresses === undefined;});
  186.     var message = opReturnOutput.scriptPubKey.asm;
  187.    
  188.     let details = {};
  189.     details.version     = message.substring(10, 18);
  190.     details.versionValid= details.version === '0abcde1e';
  191.     details.reviewee160 = message.substring(18, 58);
  192.     details.reviewee    = bitbox.Address.hash160ToCash(details.reviewee160);
  193.     details.reviewer160 = message.substring(58, 98);
  194.     details.reviewer    = bitbox.Address.hash160ToCash(details.reviewer160);
  195.     details.ratedTransaction = message.substring(98, 162);
  196.     details.ratingHex   = message.substring(162, 164);
  197.     details.rating      = details.ratingHex.toString('16')
  198.     details.signature   = Buffer.from(message.substring(164), 'hex').toString('base64');
  199.     console.log(details);
  200.  
  201.     var message = createMessage(details.reviewee, details.reviewer, details.ratedTransaction, details.rating);
  202.     details.signatureValid = bitbox.BitcoinCash.verifyMessage(
  203.         details.reviewer,
  204.         details.signature,
  205.         message.toString()
  206.     );
  207.  
  208.     details.ratedTransactionValid = await checkRatedTransactionConditions(details)
  209.  
  210.    
  211.     return details;
  212. }
  213.  
  214. async function test() {
  215.     let wallet = createWallet('sponsor access milk want fossil govern plate head stuff session banner spice attract dentist dilemma public real common what jar mad world again online');
  216.     let wallet2 = createWallet('excite orbit grit offer soon license city hybrid bring illness forward there false victory access input limb cement creek pumpkin source kitchen butter sea');
  217.  
  218.     var claimTx1 = await claimAddress(wallet)
  219.     var claimTx2 = await claimAddress(wallet2)
  220.  
  221.     await getClaimDetails(claimTx1);
  222.     await getClaimDetails(claimTx2);
  223.  
  224.     var tradeTx = await transact(wallet, wallet2, 546)
  225.  
  226.     var rateTx = await rateTransaction(bitbox.HDNode.toCashAddress(wallet2),bitbox.HDNode.toCashAddress(wallet),tradeTx,99,wallet,'mainnet')
  227.  
  228.     return await getRatingDetails(rateTx);
  229. }
  230.  
  231. test().then(console.log, console.log)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top