English
  • 简体中文
Mainnet
BSV
  • BSV
  • mBSV
  • Bits
  • Sat

Transaction

2eb7b0932cf938f10e550ac99671e7846b97e898efe52ea0b5eff85df6f584dc
( - )
244,588
2019-07-28 14:52:56
1
10,473 B

2 Outputs

Total Output:
  • j"19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAutMî'<html> <head> <style> body { font-family: monospace; font-size: 15px; margin: 10% auto; max-width: 600px; position: relative; } #qrcode { float: right; } hr { clear: both; } a { cursor: pointer; text-decoration: none; } </style> <meta charset="UTF-8" /> <script src="https://bico.media/3412b9beb4234acea4d3406c38af5e283cc91486abeddfa80fcb45842c1f99c2/"></script> <script src="https://bico.media/3bd388b0097b3bde7c8c8f5d760e1c772f5e9a002a33a42bb3440a176df21415/"></script> <!-- <script src="b://3412b9beb4234acea4d3406c38af5e283cc91486abeddfa80fcb45842c1f99c2/"></script> <script src="b://bico.media/3bd388b0097b3bde7c8c8f5d760e1c772f5e9a002a33a42bb3440a176df21415/"></script> --> <script> let privateKey; let address; let utxos = []; let readyUtxos = []; let uncomfirmedUtxos = []; let spendUtxos = []; let chunkSize = 90e3; let splitValue = 90.5e3; let splitCount; let chunks; let txns = {}; let requiredTxns; function initialize() { let wif = localStorage.getItem('privateKey'); if (wif) { privateKey = bsv.PrivateKey.fromWIF(wif); } if (!privateKey) { privateKey = bsv.PrivateKey.fromRandom(); localStorage.setItem('privateKey', privateKey.toWIF()); } address = privateKey.toAddress(); document.getElementById('address').innerText = address; const qr = qrcode(0, 'L'); qr.addData(`bitcoin:${address}?sv`); qr.make(); document.getElementById('qrcode').innerHTML = qr.createImgTag(); return fetch('https://api.bitindex.network/api/v3/addr/utxos?address=' + address, { headers: { api_key: '5eTuVfKYpWiaRWaEBN5NF1VPKf9Tvm2HBXh9mmigjNG2iC94ZCnut1SMb3sNV4hwV4', 'Content-Type': 'application/json', }, }) .then((res) => res.json()) .then(({ data }) => { utxos = data; readyUtxos = utxos.filter((utxo) => { return utxo.satoshis == splitValue && utxo.height > 0 }); uncomfirmedUtxos = utxos.filter((utxo) => { return utxo.satoshis == splitValue && !(utxo.height > 0) }); spendUtxos = utxos.filter((utxo) => utxo.satoshis != splitValue); balance = spendUtxos.reduce((balance, utxo) => { return balance + utxo.satoshis; }, 0); splitCount = Math.min(Math.floor(balance / splitValue), 500); document.getElementById('confirmed').innerText = readyUtxos.length; document.getElementById('unconfirmed').innerText = uncomfirmedUtxos.length; document.getElementById('unsplit').innerText = spendUtxos.length; document.getElementById('balance').innerText = ( utxos.reduce((balance, utxo) => { return balance + utxo.satoshis; }, 0) / 100000000 ).toFixed(4) + '🐉'; document.getElementById('splitCount').innerText = splitCount; analyzeFile(); }); } function split() { let transaction = new bsv.Transaction().from(spendUtxos); for (let i = 0; i < splitCount; i++) { transaction.to(address, splitValue); } transaction.change(address); transaction.sign(privateKey); fetch('https://api.bitindex.network/api/v3/main/tx/send', { method: 'POST', body: JSON.stringify({ rawtx: transaction.toString() }), headers: { api_key: '22qtEpsphEv2ZtP8JkBiKD65bLQ26PxyJ66obK42uCGeb3b8MetH1bK5n4xEF3yxQ4', 'Content-Type': 'application/json', }, }) .then((res) => res.json()) .then((res) => console.log(res)) .then(() => initialize()); } function analyzeFile() { const file = document.getElementById('file').files[0]; chunks = Math.ceil(file.size / chunkSize); requiredTxns = chunks + (chunks > 1 ? 1 : 0); document.getElementById('requiredTxns').innerText = requiredTxns; document.getElementById('cost').innerText = (requiredTxns * splitValue) / 100000000; document.getElementById('uploadButton').disabled = requiredTxns > readyUtxos.length; } async function upload() { const file = document.getElementById('file').files[0]; const reader = new FileReader(); txns = {}; reader.onload = async (e) => { console.log(file); let buffer = reader.result; console.log(buffer); console.log(`${chunks} chunks`); await initialize(); let i = 0; let bTxn; if (chunks > 1) { let chunkTxns = []; for (i = 0; i < chunks; i++) { let chunk = bsv.deps.Buffer.from(buffer.slice(i * chunkSize, (i + 1) * chunkSize)); let txn = new bsv.Transaction() .from(readyUtxos[i]) .addData(['1ChDHzdd1H4wSjgGMHyndZm6qxEDGjqpJL', chunk]); if (chunk.byteLength < chunkSize - 546) { txn.change(address); } txn.sign(privateKey); chunkTxns.push(txn.hash); txns[txn.hash] = { hex: txn.toString(), status: 0 }; } bTxn = new bsv.Transaction() .from(readyUtxos[i++]) .addData([ '15DHFxWZJT58f9nhyGnsRBqrgwK4W6h4Up', 'Dynamic upload', file.type, bsv.deps.Buffer.from('20', 'hex'), file.name, bsv.deps.Buffer.from('20', 'hex'), ...chunkTxns.map((txnId) => bsv.deps.Buffer.from(txnId, 'hex')), ]) .change(address) .sign(privateKey); txns[bTxn.hash] = { hex: bTxn.toString(), status: 0 }; } else { bTxn = new bsv.Transaction() .from(readyUtxos[i++]) .addData([ '19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut', bsv.deps.Buffer.from(buffer), file.type, bsv.deps.Buffer.from('20', 'hex'), file.name ]); if (buffer.byteLength < chunkSize - 546) { bTxn.change(address); } bTxn.sign(privateKey); txns[bTxn.hash] = { hex: bTxn.toString(), status: 0 }; } document.getElementById('btxn').innerHTML = '<a href="https://bico.media/' + bTxn.hash + '" target="_blank"> B://' + bTxn.hash + '</a>'; renderQueue(); await processQueue(); initialize(); }; reader.readAsArrayBuffer(file); } async function broadcast(txnId) { let txn = txns[txnId]; if(!txn) { console.error(`Missing Txn: ${txnId}`); return; } let res = await fetch('https://api.bitindex.network/api/v3/main/tx/send', { method: 'POST', body: JSON.stringify({ rawtx: txn.hex }), headers: { api_key: '22qtEpsphEv2ZtP8JkBiKD65bLQ26PxyJ66obK42uCGeb3b8MetH1bK5n4xEF3yxQ4', 'Content-Type': 'application/json', }, }); if (res.ok) { txn.status = 1; document.getElementById(txnId).innerHTML = `<a href="https://whatsonchain.com/tx/${txnId}" target="_blank">Success</a>`; } else { let error = await res.json(); txn.status = error.message.message; document.getElementById(txnId).innerHTML = `Error: ${txn.status} - <a href="javascript:void()" onclick="broadcast('${txnId}')">Retry</a>`; } } function renderQueue() { let txnList = []; for (let [hash, txn] of Object.entries(txns)) { let status; if (txn.status == 0) { status = 'Pending'; } else if (txn.status == 1) { status = `<a href="https://whatsonchain.com/tx/${hash}">Success</a>`; } else { status = `Error: ${txn.status} - <a href="javascript:void()" onclick="broadcast('${hash}')">Retry</a>`; } txnList.push(`<li><strong>${hash}</strong> - <span id="${hash}">${status}</span></li>`); } document.getElementById('queue').innerHTML = txnList.join('\n'); } async function processQueue() { let i = 0; for (let [hash, txn] of Object.entries(txns)) { if (txn.status == 1) continue; console.log(`Broadcasting: ${hash}`); await broadcast(hash); } } function refund() { let refundAddress = bsv.Address.fromString(document.getElementById('refundAddress').value); let total = utxos.reduce((acc, utxo) => { return acc + utxo.satoshis; }, 0); let txn = new bsv.Transaction() .from(utxos) .change(refundAddress) .sign(privateKey); return fetch('https://api.bitindex.network/api/v3/main/tx/send', { method: 'POST', body: JSON.stringify({ hex: txn.toString() }), headers: { api_key: '22qtEpsphEv2ZtP8JkBiKD65bLQ26PxyJ66obK42uCGeb3b8MetH1bK5n4xEF3yxQ4', 'Content-Type': 'application/json', }, }) .then((res) => res.json()) .then((res) => { console.log(res); document.getElementById('refund').innerText = txn.hash; initialize(); }); } function toggle() { if (document.getElementById('wif').style.display == 'none') { document.getElementById('wif').style.display = 'inline'; document.getElementById('wif').innerHTML = privateKey.toWIF(); } else { document.getElementById('wif').style.display = 'none'; document.getElementById('wif').innerHTML = ''; } } </script> </head> <body onload="initialize()"> <h1>Dynamic files on the blockchain</h1> <hr /> <div id="qrcode"></div> <h2>1. Fund Wallet</h2> <h4>Current address</h4> <p><span id="address"></span></p> <p> Total Balance: <span id="balance"></span> <a href="#" onclick="initialize()">🔄</a> </p> <hr /> <h2>2. Prepare UTXOs</h2> In order to bypass a limitation in the number of chained transactions allowed, split transactions and let them confirm before you upload. <a href="#" onclick="initialize()">🔄</a> <p> Ready: <span id="confirmed">?</span><br /> Unconfirmed: <span id="unconfirmed">?</span><br /> Unsplit: <span id="unsplit">?</span> <button onclick="split()">Split <span id="splitCount">0</span> Txns</button> </p> <hr /> <h2>3. Upload</h2> <p> <input type="file" id="file" onchange="analyzeFile()" /><br /> Required Txns: <span id="requiredTxns">0</span><br /> Cost: ~<span id="cost">0</span> </p> <button onclick="upload()" id="uploadButton" disabled="true">Upload</button> <p> B Txn: <span id="btxn"></span> </p> <p> Upload Queue: <span id="status"></span><br> <ul id="queue"></ul> </p> <hr /> <h4>Cash Out</h4> <p> <input type="text" id="refundAddress" placeholder="Refund Address" /> </p> <button onclick="refund()">Refund</button><br> <span id="refund"></span> <h4>Private Key</h4> <button onclick="toggle()">Show/Hide WIF</button> <p><span id="wif" style="display:none"></span></p> </body> </html> text/html
    https://whatsonchain.com/tx/2eb7b0932cf938f10e550ac99671e7846b97e898efe52ea0b5eff85df6f584dc