xcps 6 years ago
parent
commit
b47b86aff9
  1. 157
      bin/syncBlockchain.js
  2. 4
      models/block.js
  3. 62
      routes/address.js
  4. 10
      views/address.pug
  5. 4
      views/transaction.pug

157
bin/syncBlockchain.js

@ -32,6 +32,7 @@ function MakeRPCRequest(postData) {
}); });
} }
// async function saveTransaction(txid, blockHeight) {
async function saveTransaction(txid, blockHeight) { async function saveTransaction(txid, blockHeight) {
const res_tx = await MakeRPCRequest(JSON.stringify({ const res_tx = await MakeRPCRequest(JSON.stringify({
method: 'getrawtransaction', method: 'getrawtransaction',
@ -53,66 +54,121 @@ async function saveTransaction(txid, blockHeight) {
txid: tx.txid, txid: tx.txid,
BlockHeight: blockHeight, BlockHeight: blockHeight,
vouts: [], vouts: [],
vins: [],
}; };
// Loop over vouts // Loop over vouts
for (var i = 0; i < tx.vout.length; i++) { for (var i = 0; i < tx.vout.length; i++) {
const vout = tx.vout[i]; const vout = tx.vout[i];
// const m_vout = await models.Vout.create({
// n: vout.n,
// value: vout.value,
// });
const m_vout = { const m_vout = {
n: vout.n, n: vout.n,
value: vout.value, value: vout.value,
addresses: [] addresses: [],
direction: 1,
}; };
// Loop over addresses in vout // Loop over addresses in vout
for (var y = 0; y < vout.scriptPubKey.addresses.length; y++) { for (var y = 0; y < vout.scriptPubKey.addresses.length; y++) {
const address = vout.scriptPubKey.addresses[y]; const address = vout.scriptPubKey.addresses[y];
// let m_address = await models.Address.findOne({ m_vout.addresses.push(address);
// where: {
// address,
// },
// });
// if (m_address === null) {
// m_address = await models.Address.create({ /// TODO create
// address,
// });
// }
// if (m_address === null) {
// m_address = { address, };
// }
// await m_vout.addAddresses(m_address);
m_vout.push(m_address);
} }
// await transaction.addVouts(m_vout, {through: {direction: 1}}); // TODO create transaction.vouts.push(m_vout); // TODO create
transaction.addVouts(m_vout, {through: {direction: 1}}); // TODO create
} }
for (var i = 0; i < tx.vin.length; i++) { for (var i = 0; i < tx.vin.length; i++) {
const vin = tx.vin[i]; const vin = tx.vin[i];
if (vin.txid) { if (vin.txid) {
const vout = await models.Vout.findAll({ transaction.vins.push(vin);
include: {
model: models.Transaction,
where: {
txid: vin.txid,
},
},
where: {
n: vin.vout,
},
});
if (vout) {
await transaction.addVouts(vout[0], { through: { direction: 0, }, });
} else {
throw('Couldnt find vout for VIN');
}
} }
} }
return transaction;
}
async function createBlock(block) {
return models.sequelize.transaction().then(async (t) => {
try {
console.log(1)
const m_block = await models.Block.create(Object.assign({}, block, {transaction: t}));
for (var i = block.tx.length - 1; i >= 0; i--) {
tx = block.tx[i];
if (!tx) continue; // for genesis block
console.log(2)
const m_transaction = await models.Transaction.create({
txid: tx.txid,
BlockHeight: tx.BlockHeight,
transaction: t,
});
console.log(2.1, m_transaction.id, m_block.height)
await m_block.addTransaction(m_transaction, t);
console.log(2.2)
for (var y = tx.vouts.length - 1; y >= 0; y--) {
const vout = tx.vouts[y];
console.log(3)
const m_vout = await models.Vout.create({
n: vout.n,
value: vout.value,
direction: 1,
transaction: t,
});
console.log(4)
await m_transaction.addVouts(m_vout, {
through: {
direction: 1
},
transaction: t,
});
for (var z = vout.addresses.length - 1; z >= 0; z--) {
const address = vout.addresses[z];
console.log(5)
let m_address = await models.Address.findOne({
where: {
address,
},
});
if (!m_address) {
console.log(6)
m_address = await models.Address.create({
address,
transaction: t,
}, t);
}
console.log(7)
await m_vout.addAddress(m_address);
}
}
for (var y = tx.vins.length - 1; y >= 0; y--) {
const vin = tx.vins[y];
if (vin.txid) {
console.log(8)
const vout = await models.Vout.findAll({
include: {
model: models.Transaction,
where: {
txid: vin.txid,
},
},
where: {
n: vin.vout,
},
});
if (vout) {
console.log(9)
await m_transaction.addVouts(vout[0], {
through: {
direction: 0,
},
transaction: t,
});
} else {
throw('Couldnt find vout for VIN');
}
}
}
}
t.commit();
} catch (e) {
t.rollback();
console.log('===', e, 'error');
}
});
} }
async function syncNextBlock(syncedHeight) { async function syncNextBlock(syncedHeight) {
@ -130,11 +186,13 @@ async function syncNextBlock(syncedHeight) {
})); }));
const block = JSON.parse(res_block)['result']; const block = JSON.parse(res_block)['result'];
block.time = new Date(block.time * 1000); block.time = new Date(block.time * 1000);
// await models.Block.create(block);
const blockToCreate = Object.assign({}, block, {'tx': []});
for (var i = 0; i < block.tx.length; i++) { for (var i = 0; i < block.tx.length; i++) {
// await saveTransaction(block.tx[i], block.height); tx = await saveTransaction(block.tx[i], block.height);
blockToCreate.tx.push(tx);
} }
if (block.height > 1) { if (blockToCreate.height > 1) {
await models.Block.update({ await models.Block.update({
nextblockhash: block.hash nextblockhash: block.hash
},{ },{
@ -143,6 +201,7 @@ async function syncNextBlock(syncedHeight) {
} }
}); });
} }
await createBlock(blockToCreate);
return height; return height;
} }
@ -175,14 +234,18 @@ async function syncBlockchain() {
try { try {
while (syncedHeight < currentHeight) { while (syncedHeight < currentHeight) {
syncedHeight = await syncNextBlock(syncedHeight); syncedHeight = await syncNextBlock(syncedHeight);
process.stdout.write(`Synced ${syncedHeight} out of ${currentHeight}\r`); // process.stdout.write(`Synced ${syncedHeight} out of ${currentHeight}\r`);
console.log(`Synced ${syncedHeight} out of ${currentHeight}`);
if (syncedHeight >= 125)
process.exit(0)
} }
} catch (e) { } catch (e) {
console.log('=====', e); console.log('+====', e);
process.exit(0); process.exit(0);
} }
process.stdout.write('\nDone\n'); process.stdout.write('\nDone\n');
process.exit(0); process.exit(0);
} }
syncBlockchain(); syncBlockchain()
.then((res) => process.exit(0));

4
models/block.js

@ -25,7 +25,9 @@ module.exports = (sequelize, DataTypes) => {
}); });
Block.associate = function(models) { Block.associate = function(models) {
models.Block.hasMany(models.Transaction); models.Block.hasMany(models.Transaction, {
onDelete: "CASCADE",
});
}; };
return Block; return Block;

62
routes/address.js

@ -6,40 +6,54 @@ var router = express.Router();
router.get('/:address/:offset*?', async function(req, res, next) { router.get('/:address/:offset*?', async function(req, res, next) {
const safe_address = encodeURI(req.params.address); const safe_address = encodeURI(req.params.address);
const limit = 30; const limit = 3;
const paramPage = parseInt(req.params.offset);
const transactions = await models.Transaction.findAll({ const page = isNaN(paramPage) || paramPage < 1 ? 1 : paramPage;
include: { const offset = limit * (page - 1);
model: models.Vout,
include: { // const transactions = await models.Transaction.findAll({
model: models.Address, // include: {
where: { // model: models.Vout,
address: safe_address, // include: {
}, // model: models.Address,
}, // where: {
}, // address: safe_address,
// },
// },
// },
// raw: true,
// offset: offset,
// limit: limit,
// });
const vouts = await models.Vout.findAll({
raw: true, raw: true,
limit: 30, include: [{
// attributes: [],
model: models.Address,
where: {
address: safe_address,
}
}, {
attributes: ['txid'],
model: models.Transaction,
}],
// offset,
// limit,
}); });
console.log(vouts);
console.log(transactions);
if (transactions === null) { if (vouts === null) {
res.status(404).render('404'); res.status(404).render('404');
return; return;
} }
// console.log(transactions);
const nextpage = vouts.length === 30 ? page + 1 : null;
const paramPage = parseInt(req.params.offset);
const page = isNaN(paramPage) || paramPage < 1 ? 1 : paramPage;
const offset = 30 * (page - 1);
const nextpage = transactions.length === 30 ? page + 1 : null;
const prevpage = page > 1 ? page - 1 : null; const prevpage = page > 1 ? page - 1 : null;
res.render('address', { res.render('address', {
address: safe_address, address: safe_address,
transactions, vouts,
nextpage, nextpage,
prevpage, prevpage,
}); });

10
views/address.pug

@ -2,20 +2,20 @@ extends layout
block content block content
h3 Address h3 Address
div= address.address div= address
h3 Transactions h3 Transactions
table table
each transaction in transactions each vout in vouts
tr tr
if transaction['Vouts.TransactionVouts.direction'] == 1 if vout['Transactions.TransactionVouts.direction'] == 1
td INCOME td INCOME
else else
td OUTCOME td OUTCOME
td td
a(href=`/transaction/${transaction.txid}/`) #{transaction.txid} a(href=`/transaction/${vout['Transactions.txid']}/`) #{vout['Transactions.txid']}
div.pagination div.pagination
if prevpage if prevpage
a(href=`/address/#{address}/${prevpage}/`, style='float:left') Back a(href=`/address/${address}/${prevpage}/`, style='float:left') Back
if nextpage if nextpage
a(href=`/address/${address}/${nextpage}/`, style='float:right') Next a(href=`/address/${address}/${nextpage}/`, style='float:right') Next

4
views/transaction.pug

@ -46,13 +46,9 @@ block content
tr tr
th Address th Address
th Value th Value
th Transaction
each vout in transaction.vouts each vout in transaction.vouts
each address in vout.Addresses each address in vout.Addresses
tr tr
td td
a(href=`/address/${address.address}/`) #{address.address} a(href=`/address/${address.address}/`) #{address.address}
td #{vout.value} td #{vout.value}
td
each transaction in vout.Transactions
a(href=`/transaction/${transaction.txid}/`) #{transaction.txid}

Loading…
Cancel
Save