Enhance blockchain scan

This commit is contained in:
Rene Vergara 2021-11-04 07:49:09 -05:00
parent 01520adbc3
commit fa5221b128
7 changed files with 183 additions and 164 deletions

View file

@ -26,6 +26,8 @@ const rpc = stdrpc({
password: fullnode.password password: fullnode.password
}); });
var async = require('async');
const CoinGeckoClient = new CoinGecko(); const CoinGeckoClient = new CoinGecko();
var intervalObject = setInterval( function() { var intervalObject = setInterval( function() {
@ -63,6 +65,86 @@ var intervalObject = setInterval( function() {
}); });
}, 90000); }, 90000);
function hexToString(hexString) {
var str = '';
for (var n=0; n < hexString.length; n +=2) {
str += String.fromCharCode(parseInt(hexString.substr(n, 2), 16));
}
return str;
}
var blockInterval = setInterval( function() {
console.log('Node periodic Zcash scan');
//usermodel.find({}, function (err, docs) {
//if (err) {
//console.log(err);
//} else {
//console.log(session, blocktime);
//console.log(docs);
//}
//});
rpc.z_listreceivedbyaddress(fullnode.addr, 10).then(txs => {
var re = /.*ZGO::(.*)\sReply-To:\s(z\w+)/;
async.each (txs, function(txData, callback) {
var memo = hexToString(txData.memo);
if (re.test(memo)) {
//console.log('Processing tx:', memo);
var match = re.exec(memo);
if (match != null) {
var address = match[2];
var session = match[1];
var blocktime = txData.blocktime;
//console.log(' ', session, blocktime);
usermodel.findOne({address: address, session: session, blocktime: blocktime}).then(function(doc){
if (doc != null) {
console.log('Found user');
} else {
console.log('User not found', session, blocktime);
var user = new usermodel({
address: address,
session: session,
blocktime: blocktime
});
user.save(function(error) {
if (error) {
console.log(error);
}
console.log('User saved');
});
}
});
ownermodel.findOne({address: address}).then(function (oDoc) {
if (oDoc != null) {
console.log('Found owner');
} else {
console.log('Owner not found', session);
var owner = new ownermodel({
address: address,
name: 'Z-Go-'.concat(address.substring(0,5))
});
owner.save().then(function(err) {
if (err) {
console.log(err);
}
console.log('Owner saved!');
});
}
}).catch((err) => {
console.log(err);
});
}
}
}, function (err) {
if (err) {
console.log(err);
}
console.log('Txs synced');
});
});
}, 90000);
app.use(bodyparser.json()); app.use(bodyparser.json());
app.use((req, res, next) => { app.use((req, res, next) => {
@ -73,73 +155,41 @@ app.use((req, res, next) => {
next(); next();
}); });
app.post('/api/posts', (req, res, next) => {
const post = new postmodel({
title: req.body.title,
content: req.body.content
});
post.save();
//console.log(req.ip);
res.status(201).json({
message: 'Post added successfully'
});
});
app.get('/api/posts', (req, res, next) => {
postmodel.find().
then((documents) => {
//console.log(documents);
res.status(200).json({
message: 'Posts Fetched successfully',
posts: documents
});
});
});
/*
* Add a new user
* @param address: String. Shielded zcash address
* @param session: String. Browser session uuid
* @param blocktime: Number. Blocktime of login zcash transaction
*/
app.post('/api/users', (req, res, next) => {
console.log('Post: /api/users');
const user = new usermodel({
address: req.body.address,
session: req.body.session,
blocktime: req.body.blocktime
});
user.save();
res.status(201).json({
message: 'User added successfully'
});
});
app.get('/api/users', (req, res, next) => { app.get('/api/users', (req, res, next) => {
console.log('Get: /api/users'); console.log('Get: /api/users');
usermodel.find({'address': req.query.address, 'session': req.query.session}). usermodel.find({'address': req.query.address, 'session': req.query.session}).
then((documents) => { then((documents) => {
console.log("Searching"); if (documents != null) {
res.status(200).json({ res.status(200).json({
message: 'Users found successfully', message: 'Users found successfully',
users: documents users: documents
}); });
} else {
res.status(204).json({
message: 'User not found',
users: null
});
}
}); });
}); });
app.get('/api/getuser', (req, res, next) => { app.get('/api/getuser', (req, res, next) => {
console.log('Get: /api/getuser/', req.query.session); console.log('Get: /api/getuser/', req.query.session);
usermodel.find({'session': req.query.session}). var today = new Date().getTime() / 1000;
var expiration = today - (7*24*3600);
usermodel.find({'session': req.query.session, 'blocktime': { $gt: expiration }}).
then((documents) => { then((documents) => {
console.log("Searching for user...");
if(documents.length > 0){ if(documents.length > 0){
//console.log(documents); //console.log(documents);
console.log(' found user');
res.status(200).json({ res.status(200).json({
message: 'User found!', message: 'User found!',
user: documents user: documents
}); });
} else { } else {
console.log(' did not find user');
res.status(204).json({ res.status(204).json({
message: 'User not found!', message: 'User not found!',
user: null user: null
@ -159,9 +209,10 @@ app.get('/api/blockheight', (req, res, next) => {
}); });
app.get('/api/txs', (req, res, next) => { app.get('/api/txs', (req, res, next) => {
console.log('Get: /api/txs'); console.log('Get: /api/txs');
rpc.z_listreceivedbyaddress(fullnode.addr, 5).then(txs => { rpc.z_listreceivedbyaddress(fullnode.addr, 10).then(txs => {
res.status(200).json({ res.status(200).json({
message: 'Transactions found', message: 'Transactions found',
txs: txs txs: txs

View file

@ -1,7 +1,7 @@
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const ownerSchema = mongoose.Schema({ const ownerSchema = mongoose.Schema({
address: {type: String, required:true}, address: {type: String, required:true, unique:true},
name: {type: String, required:true} name: {type: String, required:true}
}); });

43
package-lock.json generated
View file

@ -1,11 +1,11 @@
{ {
"name": "sell4zec", "name": "zgo",
"version": "0.0.0", "version": "0.0.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "sell4zec", "name": "zgo",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@angular/animations": "~12.2.0", "@angular/animations": "~12.2.0",
@ -20,6 +20,7 @@
"@angular/router": "~12.2.0", "@angular/router": "~12.2.0",
"@supercharge/request-ip": "^1.1.2", "@supercharge/request-ip": "^1.1.2",
"angular-local-storage": "^0.7.1", "angular-local-storage": "^0.7.1",
"async": "^3.2.2",
"coingecko-api": "^1.0.10", "coingecko-api": "^1.0.10",
"easyqrcodejs": "^4.4.6", "easyqrcodejs": "^4.4.6",
"material-design-icons": "^3.0.1", "material-design-icons": "^3.0.1",
@ -3251,13 +3252,9 @@
} }
}, },
"node_modules/async": { "node_modules/async": {
"version": "2.6.3", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
}
}, },
"node_modules/async-each": { "node_modules/async-each": {
"version": "1.0.3", "version": "1.0.3",
@ -10305,6 +10302,15 @@
"node": ">= 0.12.0" "node": ">= 0.12.0"
} }
}, },
"node_modules/portfinder/node_modules/async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
}
},
"node_modules/portfinder/node_modules/debug": { "node_modules/portfinder/node_modules/debug": {
"version": "3.2.7", "version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
@ -17997,13 +18003,9 @@
"dev": true "dev": true
}, },
"async": { "async": {
"version": "2.6.3", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
"dev": true,
"requires": {
"lodash": "^4.17.14"
}
}, },
"async-each": { "async-each": {
"version": "1.0.3", "version": "1.0.3",
@ -23475,6 +23477,15 @@
"mkdirp": "^0.5.5" "mkdirp": "^0.5.5"
}, },
"dependencies": { "dependencies": {
"async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"requires": {
"lodash": "^4.17.14"
}
},
"debug": { "debug": {
"version": "3.2.7", "version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",

View file

@ -22,6 +22,7 @@
"@angular/router": "~12.2.0", "@angular/router": "~12.2.0",
"@supercharge/request-ip": "^1.1.2", "@supercharge/request-ip": "^1.1.2",
"angular-local-storage": "^0.7.1", "angular-local-storage": "^0.7.1",
"async": "^3.2.2",
"coingecko-api": "^1.0.10", "coingecko-api": "^1.0.10",
"easyqrcodejs": "^4.4.6", "easyqrcodejs": "^4.4.6",
"material-design-icons": "^3.0.1", "material-design-icons": "^3.0.1",

View file

@ -21,7 +21,6 @@ export class FullnodeService{
constructor(private http: HttpClient, public userService: UserService){ constructor(private http: HttpClient, public userService: UserService){
this.getAddr(); this.getAddr();
this.getHeight(); this.getHeight();
this.getMemos();
this.getPrice(); this.getPrice();
} }
@ -60,42 +59,6 @@ export class FullnodeService{
return str; return str;
} }
getMemos() {
this.http.get<{message: string, txs: any}>('http://localhost:3000/api/txs').
subscribe((TxData) => {
var memos: string[] = [];
//this.addr = TxData.addr;
var re = /.*ZGO::(.*)\sReply-To:\s(z\w+)/;
for (var i=0; i < TxData.txs.length; i++) {
var memo = this.hexToString(TxData.txs[i].memo);
//console.log(TxData.txs[i].blocktime);
if (re.test(memo)){
memos.push(memo);
var match = re.exec(memo);
if (match != null) {
var address = match[2];
var session = match[1];
var blocktime = TxData.txs[i].blocktime;
console.log(memo);
console.log(`Searching for user for ${session}`);
const params = new HttpParams().append('session', session);
this.http.get<{message: string, user: any}>('http://localhost:3000/api/getuser', { headers:{}, params: params, observe: 'response'}).
subscribe((UserDataResponse) => {
console.log(UserDataResponse.status);
if (UserDataResponse.status == 200){
console.log(`FS: Found user`);
} else {
console.log('FS: Did not find user');
this.userService.addUser(address, session, blocktime);
}
});
}
}
}
this.dataStore.memoList = memos;
this._memoUpdated.next(Object.assign({},this.dataStore).memoList);
});
}
getAddr() { getAddr() {

View file

@ -17,7 +17,6 @@ var Buffer = require('buffer/').Buffer;
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
intervalHolder: any; intervalHolder: any;
memos: string[] = [];
nodeAddress: string = ''; nodeAddress: string = '';
private FullnodeSub: Subscription = new Subscription(); private FullnodeSub: Subscription = new Subscription();
private UserSub: Subscription = new Subscription(); private UserSub: Subscription = new Subscription();
@ -46,18 +45,9 @@ export class LoginComponent implements OnInit {
if(localToken == null){ if(localToken == null){
var token = uuidv4(); var token = uuidv4();
localStorage.setItem('s4z_token', token); localStorage.setItem('s4z_token', token);
console.log('Showing QR code for login'); localToken = token;
console.log(URLSafeBase64.encode(Buffer.from('ZGO::'.concat(token)))); }
var codeString = `zcash:${this.nodeAddress}?amount=0.001&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(token)))}`; this.userService.findUser();
console.log(codeString);
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: codeString,
logo: "/assets/zcash.png",
logoWidth: 80,
logoHeight: 80
});
} else {
//this.userService.getUser(localToken);
this.userService.uZaddrUpdate. this.userService.uZaddrUpdate.
subscribe((userAddr: string) => { subscribe((userAddr: string) => {
if (userAddr.length != 0) { if (userAddr.length != 0) {
@ -77,15 +67,25 @@ export class LoginComponent implements OnInit {
}); });
} }
}); });
}
}); });
this.intervalHolder = setInterval(() => { this.intervalHolder = setInterval(() => {
this.fullnodeService.getHeight(); this.fullnodeService.getHeight();
this.fullnodeService.getMemos(); //this.userService.findUser();
this.loginCheck();
this._changeDetectorRef.markForCheck(); this._changeDetectorRef.markForCheck();
}, 1000 * 75); }, 1000 * 75);
} }
loginCheck(){
this.userService.findUser();
this.uZaddrUpdate.subscribe((userAddr: string) => {
if (userAddr.length != 0) {
console.log('Log in found in blockchain!');
this.router.navigate(['/view']);
}
});
}
ngOnDestroy(){ ngOnDestroy(){
this.FullnodeSub.unsubscribe(); this.FullnodeSub.unsubscribe();
this.UserSub.unsubscribe(); this.UserSub.unsubscribe();

View file

@ -38,6 +38,8 @@ export class UserService{
} }
findUser() { findUser() {
this.session = localStorage.getItem('s4z_token');
if (this.session != null) {
const params = new HttpParams().append('session', this.session!); const params = new HttpParams().append('session', this.session!);
let obs = this.http.get<{message: string, user: any}>('http://localhost:3000/api/getuser', { headers:{}, params: params, observe: 'response'}); let obs = this.http.get<{message: string, user: any}>('http://localhost:3000/api/getuser', { headers:{}, params: params, observe: 'response'});
@ -55,21 +57,12 @@ export class UserService{
}); });
return obs; return obs;
} else {
console.log('No session loaded');
return null;
}
} }
addUser(address: string, session: string, blocktime: number) {
const user: User={_id: '', address: address, session: session, blocktime: blocktime};
let obs = this.http.post<{message: string}>('http://localhost:3000/api/users', user);
obs.subscribe((responseData) => {
console.log(responseData.message);
this.getOwner(address).subscribe((response) => {
console.log('addUser, checking owner', response);
});
});
return obs;
}
addOwner(address: string) { addOwner(address: string) {
const owner: Owner={_id: '', address: address, name: 'Zgo-'.concat(address.substring(0,5))}; const owner: Owner={_id: '', address: address, name: 'Zgo-'.concat(address.substring(0,5))};