update to newer version
This commit is contained in:
parent
d6a32870bc
commit
29138de53e
37 changed files with 15795 additions and 12789 deletions
BIN
blockchain/.DS_Store → .DS_Store
vendored
BIN
blockchain/.DS_Store → .DS_Store
vendored
Binary file not shown.
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,6 +3,4 @@
|
|||
################################################################################
|
||||
|
||||
/.vs
|
||||
/.vscode
|
||||
/node_modules
|
||||
/.metals
|
||||
|
|
13
Notes
13
Notes
|
@ -1,13 +0,0 @@
|
|||
npm run dev
|
||||
PORT=3002 P2P_PORT=5002 PEERS=ws://localhost:5001 npm run dev
|
||||
PORT=3003 P2P_PORT=5003 PEERS=ws://localhost:5001,ws://localhost:5002 npm run dev
|
||||
PORT=3004 P2P_PORT=5004 PEERS=ws://localhost:5001,ws://localhost:5002,ws://localhost:5003 npm run dev
|
||||
PORT=3005 P2P_PORT=5005 PEERS=ws://localhost:5001,ws://localhost:5002,ws://localhost:5003,ws://localhost:5004 npm run dev
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
* in this version, on top of adding Mqtt broker to each node and adding new module called integration and integrationVirtual
|
||||
* we ad blockNum to each block, and we limited the number of transaction for each block
|
47
Query.json
47
Query.json
|
@ -1,47 +0,0 @@
|
|||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
||||
undefined
|
92
README.md
92
README.md
|
@ -1,92 +0,0 @@
|
|||
# SenShaMart
|
||||
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||
|
||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||
|
||||
## Add your files
|
||||
|
||||
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin https://gitlab.com/swinburne-iot-lab/senshamart.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
|
||||
- [ ] [Set up project integrations](https://gitlab.com/swinburne-iot-lab/senshamart/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||
|
||||
## Test and Deploy
|
||||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
|
||||
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||
|
||||
***
|
||||
|
||||
# Editing this README
|
||||
|
||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||
|
||||
## Suggestions for a good README
|
||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||
|
||||
## Name
|
||||
Choose a self-explaining name for your project.
|
||||
|
||||
## Description
|
||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||
|
||||
## Badges
|
||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||
|
||||
## Visuals
|
||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||
|
||||
## Installation
|
||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||
|
||||
## Usage
|
||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||
|
||||
## Support
|
||||
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||
|
||||
## Roadmap
|
||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||
|
||||
## Contributing
|
||||
State if you are open to contributions and what your requirements are for accepting them.
|
||||
|
||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||
|
||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||
|
||||
## Authors and acknowledgment
|
||||
Show your appreciation to those who have contributed to the project.
|
||||
|
||||
## License
|
||||
For open source projects, say how it is licensed.
|
||||
|
||||
## Project status
|
||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
BIN
app/.DS_Store
vendored
BIN
app/.DS_Store
vendored
Binary file not shown.
493
app/index.js
493
app/index.js
|
@ -27,73 +27,53 @@
|
|||
* to monitor the node
|
||||
*
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const Blockchain = require('../blockchain');
|
||||
const P2pServer = require('./p2p-server');
|
||||
const Wallet = require('../wallet');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const Blockchain = require('../blockchain');
|
||||
const P2pServer = require('./p2p-server');
|
||||
const Wallet = require('../wallet');
|
||||
const TransactionPool = require('../wallet/transaction-pool');
|
||||
const Miner = require('./miner');
|
||||
const morgan = require('morgan');//AddedM
|
||||
const multer = require('multer');
|
||||
//const productRoutes = require("./products");//addedM
|
||||
const newEngine = require('@comunica/actor-init-sparql').newEngine;
|
||||
const Miner = require('./miner');
|
||||
const QueryEngine = require('@comunica/query-sparql').QueryEngine;
|
||||
|
||||
const N3 = require('n3');
|
||||
const jsonld = require('jsonld');
|
||||
const DataFactory = require('n3').DataFactory;
|
||||
const fs = require('fs');
|
||||
const swaggerUi = require('swagger-ui-express')
|
||||
const swaggerFile = require('./swagger_output.json')
|
||||
var lodash = require('lodash');
|
||||
var mqtt = require('mqtt');
|
||||
var aedes = require('aedes')();
|
||||
var aedes = require('aedes')(); /* aedes is a stream-based MQTT broker */
|
||||
var MQTTserver = require('net').createServer(aedes.handle);
|
||||
var mosca = require('mosca');
|
||||
//var awsIot = require('aws-iot-device-sdk');
|
||||
'use strict';// "use strict" is to indicate that the code should be executed in "strict mode".
|
||||
// With strict mode, you can not, for example, use undeclared variables.
|
||||
const fs = require('fs'); /* file system (fs) module allows you to work with
|
||||
the file system on your computer*/
|
||||
const multer = require('multer');/* Multer is a node.js middleware for handling multipart/form-data
|
||||
, which is primarily used for uploading files.*/
|
||||
'use strict';/* "use strict" is to indicate that the code should be executed in "strict mode".
|
||||
With strict mode, you can not, for example, use undeclared variables.*/
|
||||
|
||||
|
||||
const app = express();
|
||||
const bc = new Blockchain();
|
||||
const wallet = new Wallet();
|
||||
const tp = new TransactionPool();
|
||||
const p2pServer = new P2pServer(bc, tp);
|
||||
const miner = new Miner(bc, tp, wallet, p2pServer);
|
||||
|
||||
const parser = new N3.Parser({format: 'application/n-quads'});
|
||||
const store = new N3.Store();
|
||||
const store2 = new N3.Store();
|
||||
const myEngine = newEngine();
|
||||
const app = express();
|
||||
const bc = new Blockchain();
|
||||
const wallet = new Wallet();
|
||||
const tp = new TransactionPool();
|
||||
const p2pServer = new P2pServer(bc, tp);
|
||||
const miner = new Miner(bc, tp, wallet, p2pServer);
|
||||
const myEngine = new QueryEngine();
|
||||
|
||||
//var client = mqtt.connect('mqtt://broker.hivemq.com');
|
||||
app.use(bodyParser.json());
|
||||
|
||||
var MOSCAsettings = { MOSCAport:1883 }
|
||||
//var MOSCAserver = new mosca.Server(MOSCAsettings);
|
||||
|
||||
|
||||
//Mosca mqtt server intialization
|
||||
// MOSCAserver.on('ready', function(){
|
||||
// console.log("ready");
|
||||
// });
|
||||
|
||||
//aedes mqtt server intialization
|
||||
const MQTTport = process.env.MQTT_PORT || 1883;
|
||||
MQTTserver.listen(MQTTport, function () {
|
||||
console.log('MQTTserver listening on port', MQTTport)
|
||||
})
|
||||
|
||||
//
|
||||
//initialising a local storage for storing metadata file initially before storing it in the tripple store
|
||||
const storage = multer.diskStorage({
|
||||
destination: function(req, file, cb) {
|
||||
cb(null, './uploads/');
|
||||
},
|
||||
filename: function(req, file, cb) {
|
||||
cb(null, new Date().toISOString() + file.originalname);
|
||||
cb(null, new Date().toISOString() + file.originalname);
|
||||
}
|
||||
});
|
||||
|
||||
//filtering the type of uploaded files
|
||||
const fileFilter = (req, file, cb) => {
|
||||
//filtering the type of uploaded Metadata files
|
||||
const fileFilter = (req, file, cb) => {
|
||||
// reject a file
|
||||
if (file.mimetype === 'application/json' || file.mimetype === 'text/plain' ) {
|
||||
cb(null, true);
|
||||
|
@ -101,7 +81,7 @@ const fileFilter = (req, file, cb) => {
|
|||
cb(null, false);
|
||||
}
|
||||
};
|
||||
|
||||
// defining a storage and setup limits for storing metadata file initially before storing it in the tripple store
|
||||
const upload = multer({
|
||||
storage: storage,
|
||||
limits: {
|
||||
|
@ -110,89 +90,54 @@ const upload = multer({
|
|||
fileFilter: fileFilter
|
||||
});
|
||||
|
||||
const port = process.env.HTTP_PORT || 3001;
|
||||
// innitialising the HTTP PORT to listen
|
||||
const port = process.env.HTTP_PORT || 3000;
|
||||
app.listen(port, () => console.log(`Listening on port ${port}`));
|
||||
p2pServer.listen();
|
||||
|
||||
app.use('/doc', swaggerUi.serve, swaggerUi.setup(swaggerFile))
|
||||
//aedes mqtt server intialization
|
||||
const MQTTport = process.env.MQTT_PORT || 1882;
|
||||
MQTTserver.listen(MQTTport, function () {
|
||||
console.log('MQTTserver listening on port', MQTTport)
|
||||
})
|
||||
|
||||
function log(message) {
|
||||
console.log(`New block added: ${message.toString()}`);
|
||||
// fs.writeFileSync('./blocks.json', JSON.stringify(message),{'flags': 'a'}); //the problem with this function was overwrite even when i changed the flag to 'a'
|
||||
// fs.appendFile('./blocks.json', JSON.stringify(message) ,function(err){ //this function makes erorrs when the data is big
|
||||
// if(err) throw err;
|
||||
// console.log('IS WRITTEN')
|
||||
// });
|
||||
var BlockStream = fs.createWriteStream("blocks.json", {flags:'a'});
|
||||
BlockStream.write(message+ "\n");
|
||||
}
|
||||
app.use('/uploads', express.static('uploads')); // to store uploaded metadata to '/uploads' folder
|
||||
app.use(bodyParser.json()); //
|
||||
|
||||
function logQuery(message) {
|
||||
//console.log(`New block added: ${message.toString()}`);
|
||||
// fs.writeFileSync('./blocks.json', JSON.stringify(message),{'flags': 'a'}); //the problem with this function was overwrite even when i changed the flag to 'a'
|
||||
// fs.appendFile('./blocks.json', JSON.stringify(message) ,function(err){ //this function makes erorrs when the data is big
|
||||
// if(err) throw err;
|
||||
// console.log('IS WRITTEN')
|
||||
// });
|
||||
var QueryStream = fs.createWriteStream("Query.json", {flags:'a'});
|
||||
QueryStream.write(message+ "\n");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
app.use(morgan("dev"));//AddedM
|
||||
app.use('/uploads', express.static('uploads'));
|
||||
app.use(bodyParser.urlencoded({ extended: false }));//addedM
|
||||
app.use(bodyParser.json());
|
||||
//addedM
|
||||
app.use((req, res, next) => {
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header(
|
||||
"Access-Control-Allow-Headers",
|
||||
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
|
||||
);
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
|
||||
return res.status(200).json({});
|
||||
}
|
||||
next();
|
||||
});
|
||||
//finished AddedM
|
||||
|
||||
//GET functions
|
||||
// GET APIs
|
||||
app.get('/blocks', (req, res) => {
|
||||
res.json(bc.chain);
|
||||
res.json(bc.chain);
|
||||
});
|
||||
|
||||
///////////////
|
||||
app.get('/MetaDataTransactions', (req, res) => {
|
||||
res.json(tp.metaDataTransactions);
|
||||
res.json(tp.metadataS);
|
||||
});
|
||||
|
||||
app.get('/CoinTransactions', (req, res) => {
|
||||
res.json(tp.cointransactions);
|
||||
///////////////
|
||||
app.get('/PaymentTransactions', (req, res) => {
|
||||
res.json(tp.transactions);
|
||||
});
|
||||
|
||||
///////////////
|
||||
app.get('/Transactions', (req, res) => {
|
||||
res.json(tp);
|
||||
});
|
||||
|
||||
///////////////
|
||||
app.get('/mine-transactions', (req, res) => {
|
||||
const block = miner.mine();
|
||||
console.log(`New block added: ${block.toString()}`);
|
||||
//res.redirect('/blocks');
|
||||
res.json("Block mined");
|
||||
});
|
||||
|
||||
///////////////
|
||||
app.get('/public-key', (req, res) => {
|
||||
res.json({ publicKey: wallet.publicKey });
|
||||
});
|
||||
|
||||
///////////////
|
||||
app.get('/Balance', (req, res) => {
|
||||
res.json({ Balance: wallet.balance });
|
||||
});
|
||||
/////////////////////////////
|
||||
|
||||
//POST functions
|
||||
//////////////////////////////////////////////////
|
||||
// POST APIs
|
||||
app.post('/mine', (req, res) => {
|
||||
const block = bc.addBlock(req.body.data);
|
||||
console.log(`New block added: ${block.toString()}`);
|
||||
|
@ -200,9 +145,16 @@ app.post('/mine', (req, res) => {
|
|||
p2pServer.syncChains();
|
||||
|
||||
res.redirect('/blocks');
|
||||
});
|
||||
///////////////
|
||||
app.post('/transact', (req, res) => {
|
||||
const { recipient, amount } = req.body;
|
||||
const transaction = wallet.createTransaction(recipient, amount, bc, tp);
|
||||
p2pServer.broadcastTransaction(transaction);
|
||||
res.redirect('/transactions');
|
||||
});
|
||||
|
||||
app.post('/RegistringIoTdevice', (req, res)=> {
|
||||
///////////////
|
||||
app.post('/IoTdeviceRegistration', (req, res)=> {
|
||||
const {Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail,
|
||||
OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte,
|
||||
PaymentPerMinute,Protocol, MessageAttributes, Interval,
|
||||
|
@ -227,7 +179,7 @@ app.post('/RegistringIoTdevice', (req, res)=> {
|
|||
let MessageAttributesIn = MessageAttributes;
|
||||
let IntervalIn = Interval;
|
||||
let FurtherDetailsIn = FurtherDetails;
|
||||
var metaDataTransaction = wallet.createMetaDataTransaction(NameIn,
|
||||
var metaDataTransaction = wallet.createMetadata(NameIn,
|
||||
GeoIn, IP_URLIn,Topic_TokenIn,
|
||||
PermissionIn, RequestDetailIn, OrgOwnerIn,
|
||||
DepOwnerIn, PrsnOwnerIn, PaymentPerKbyteIn,
|
||||
|
@ -235,30 +187,30 @@ app.post('/RegistringIoTdevice', (req, res)=> {
|
|||
MessageAttributesIn, IntervalIn,
|
||||
FurtherDetailsIn,
|
||||
SSNmetadata, tp);
|
||||
p2pServer.broadcastMetaDataTransaction(metaDataTransaction);});
|
||||
res.json("MetadataTransactionCreated");});
|
||||
|
||||
/**
|
||||
* the following piece of code
|
||||
* is for storing the metadata as a Nquad format inside the blockchain
|
||||
*/
|
||||
// jsonld.toRDF(metaDataTransaction.SSNmetadata, {format: 'application/n-quads'},
|
||||
// (err, nquads) => {
|
||||
// // nquads is a string of N-Quads
|
||||
// parser.parse(
|
||||
// nquads,
|
||||
// (error, quadN, prefixes) => {
|
||||
// // console.log(quadN)
|
||||
// if (quadN)
|
||||
// //console.log(quadN.predicate)
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode(quadN.subject.id),
|
||||
// DataFactory.namedNode(quadN.predicate.id),
|
||||
// DataFactory.namedNode(quadN.object.id)));
|
||||
// });
|
||||
// });
|
||||
// metaDataTransaction.SSNmetadata= store;
|
||||
jsonld.toRDF(metaDataTransaction.SSNmetadata, {format: 'application/n-quads'},
|
||||
(err, nquads) => {
|
||||
// nquads is a string of N-Quads
|
||||
parser.parse(
|
||||
nquads,
|
||||
(error, quadN, prefixes) => {
|
||||
// console.log(quadN)
|
||||
if (quadN)
|
||||
//console.log(quadN.predicate)
|
||||
store.addQuad(DataFactory.quad(
|
||||
DataFactory.namedNode(quadN.subject.id),
|
||||
DataFactory.namedNode(quadN.predicate.id),
|
||||
DataFactory.namedNode(quadN.object.id)));
|
||||
});
|
||||
});
|
||||
metaDataTransaction.SSNmetadata= store;
|
||||
p2pServer.broadcastMetadata(metaDataTransaction);});
|
||||
res.json("MetadataTransactionCreated");});
|
||||
|
||||
///////////////
|
||||
app.post('/IoTdevicePaymentTransaction', (req, res) => {
|
||||
const { Recipient_payment_address, Amount_of_money, Payment_method,
|
||||
Further_details} = req.body;
|
||||
|
@ -275,78 +227,54 @@ app.post('/IoTdevicePaymentTransaction', (req, res) => {
|
|||
res.redirect('/PayPalTransaction')
|
||||
}
|
||||
});
|
||||
|
||||
///////////////
|
||||
app.post("/UploadMetafile", upload.single('file'), (req, res) => {
|
||||
// recipient: req.body.recipient,
|
||||
// amount : req.body.amount,
|
||||
// const Geo = req.body.Geo;
|
||||
// const IPSO = req.body.IPSO;
|
||||
// const Type = req.body.Type;
|
||||
// const Permission = req.body.Permission;
|
||||
// const OrgOwner = req.body.OrgOwner;
|
||||
const file = req.file;
|
||||
//file : req.body.file
|
||||
res.status(201).json({
|
||||
message: 'Uploading Metadata was successful',
|
||||
MetadataFile : file
|
||||
});
|
||||
// recipient: req.body.recipient,
|
||||
// amount : req.body.amount,
|
||||
// const Geo = req.body.Geo;
|
||||
// const IPSO = req.body.IPSO;
|
||||
// const Type = req.body.Type;
|
||||
// const Permission = req.body.Permission;
|
||||
// const OrgOwner = req.body.OrgOwner;
|
||||
const file = req.file;
|
||||
//file : req.body.file
|
||||
res.status(201).json({
|
||||
message: 'Uploading Metadata was successful',
|
||||
MetadataFile : file
|
||||
});
|
||||
|
||||
//////simple search engine
|
||||
app.post('/selectedMeta', (req, res) => {
|
||||
const {Name}= req.body;
|
||||
data =bc.chain.map (a => a.data);
|
||||
var PickedSensors = [];
|
||||
for (let i= 1; i<data.length; i++ ){
|
||||
//var pickeditems = [null];
|
||||
|
||||
var metadata= data[i][1];
|
||||
//pickeditems.push(...metadata);
|
||||
// }
|
||||
// return meta_array.Geo === 30;
|
||||
//meta_array=bc.chain.map(b => b.input);
|
||||
|
||||
var picked = lodash.find(metadata, x=> x.Name === Name);
|
||||
if (picked != null){
|
||||
PickedSensors.push(picked);
|
||||
}
|
||||
}
|
||||
|
||||
res.json(PickedSensors);
|
||||
|
||||
});
|
||||
|
||||
/////////////////////
|
||||
//Start of comunica sparql query code
|
||||
/**
|
||||
* this code under construction
|
||||
* try Comunica SPARQL RDFJS
|
||||
* I believe we need to change the way of storing the metadata
|
||||
*/
|
||||
app.post('/sparql', (req, res) => {
|
||||
app.post('/sparql', (req, res) => {
|
||||
const {Select,subject,predicate,object,Limit}= req.body; /**these
|
||||
variable are used for the sparql query*/
|
||||
var meta = []//represents the array of all metadata inside blockchain
|
||||
var queryResult
|
||||
BlockData =bc.chain.map (a => a.data); /** extracting the data section
|
||||
from each block inside the whole blockchain */
|
||||
var i;//i represents the number of blocks inside the whole blockchain
|
||||
for ( i= 1; i < BlockData.length; i++ ){
|
||||
var j //represents number of metadata transaction inside each block
|
||||
for ( j= 0; j<BlockData[i][1].length ;j++){
|
||||
meta.push(BlockData[i][1][j]["SSNmetadata"]); } }
|
||||
parser.parse(
|
||||
nquads,
|
||||
(error, quadN, prefixes) => {
|
||||
if (quadN)
|
||||
store.addQuad(DataFactory.quad(
|
||||
DataFactory.namedNode(quadN.subject.id),
|
||||
DataFactory.namedNode(quadN.predicate.id),
|
||||
DataFactory.namedNode(quadN.object.id)));
|
||||
else {(console.log("no metadata"))
|
||||
store.addQuad(DataFactory.quad(
|
||||
DataFactory.namedNode('http://ex.org/null'),
|
||||
DataFactory.namedNode('http://ex.org/null'),
|
||||
DataFactory.namedNode('http://ex.org/null')));}});
|
||||
// BlockData =bc.chain.map (a => a.data); /** extracting the data section
|
||||
// from each block inside the whole blockchain */
|
||||
// var i;//i represents the number of blocks inside the whole blockchain
|
||||
// for ( i= 1; i < BlockData.length; i++ ){
|
||||
// var j //represents number of metadata transaction inside each block
|
||||
// for ( j= 0; j<BlockData[i][1].length ;j++){
|
||||
// meta.push(BlockData[i][1][j]["SSNmetadata"]); } }
|
||||
// parser.parse(
|
||||
// nquads,
|
||||
// (error, quadN, prefixes) => {
|
||||
// if (quadN)
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode(quadN.subject.id),
|
||||
// DataFactory.namedNode(quadN.predicate.id),
|
||||
// DataFactory.namedNode(quadN.object.id)));
|
||||
// else {(console.log("no metadata"))
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode('http://ex.org/null'),
|
||||
// DataFactory.namedNode('http://ex.org/null'),
|
||||
// DataFactory.namedNode('http://ex.org/null')));}});
|
||||
const start = async function (a,b){
|
||||
const result = await myEngine.query(`SELECT ${Select} WHERE
|
||||
{${subject} ${predicate} ${object}} LIMIT
|
||||
|
@ -356,195 +284,10 @@ app.post('/sparql', (req, res) => {
|
|||
console.log(data.toObject()));
|
||||
queryResult= result.bindingsStream};
|
||||
start()
|
||||
logQuery(queryResult);
|
||||
// logQuery(queryResult);
|
||||
res.json(queryResult);});
|
||||
|
||||
|
||||
|
||||
// this code to query the nquad data straight forward from the blockchain without changing the formt
|
||||
app.post('/sparql2', (req, res) => {
|
||||
//find a way to define default values for the comming variables
|
||||
const {Select,subject,predicate,object,Limit}= req.body; // these variable are used for the sparql query
|
||||
var meta = [] // represents the array of all metadata inside the blockchain
|
||||
var queryResult
|
||||
/**
|
||||
* change the following code to custome map function to remove the for loop
|
||||
* and make the code faster
|
||||
*/
|
||||
BlockData =bc.chain.map (a => a.data); //extracting the data section from each block inside the whole blockchain
|
||||
var i;//i represents the number of blocks inside the whole blockchain
|
||||
for ( i= 1; i < BlockData.length; i++ ){ /**the purpose of this for loop is passing each BlockData to check for metadata
|
||||
this loop could be avoided if we used custome map function */
|
||||
|
||||
var j // j represents the number of metadata transaction inside each block
|
||||
for ( j= 0; j<BlockData[i][1].length ;j++){ /** the purpose of this for loop is passing each metadata transaction inside each block
|
||||
this loop could be avoided if we used custome map function */
|
||||
meta.push(BlockData[i][1][j]["SSNmetadata"]); /**this array depends on the structure of the data section from chain from bc
|
||||
i represents the number of blocks inside the whole blockchain
|
||||
j represents the number of metadarta transaction inside each block */
|
||||
}
|
||||
|
||||
}
|
||||
console.log(meta) // printing the metadata just for testing purposes
|
||||
|
||||
// jsonld.toRDF(meta, {format: 'application/n-quads'}, (err, nquads) => { /**
|
||||
|
||||
// parser.parse( /**this piece of code is used for parse the metadata and store it in N3store */
|
||||
// nquads,
|
||||
// (error, quadN, prefixes) => {
|
||||
// // console.log(quadN)
|
||||
// if (quadN)
|
||||
// store2.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode(meta.subject.id), DataFactory.namedNode(meta.predicate.id), DataFactory.namedNode(meta.object.id)));
|
||||
// // console.log(store)
|
||||
// });
|
||||
|
||||
// const start = async function (a,b){ // we need this line of code to allow "await" function to work because it requires async function
|
||||
// const result = await myEngine.query(`SELECT ${Select} WHERE {${subject} ${predicate} ${object}} LIMIT ${Limit}`,
|
||||
// { sources: [{ type: 'rdfjsSource', value: meta}] })
|
||||
// result.bindingsStream.on('data', (data) => console.log(data.toObject()));
|
||||
// queryResult= result.bindingsStream
|
||||
// // console.log(queryResult)
|
||||
// };
|
||||
// start()
|
||||
// res.json(queryResult);
|
||||
|
||||
});
|
||||
|
||||
//try to make it return the query results insted of the metadata
|
||||
|
||||
|
||||
//});
|
||||
|
||||
/**
|
||||
* this part is an implementation for sparql-engine
|
||||
* any line code will be added for this reason will have a comment of "sparql-engne"
|
||||
*
|
||||
*/
|
||||
// const {Parser, Store }=require('n3');
|
||||
// const {Graph, HashMapDataset, PlanBuilder}= require('sparql-engine');//sparql-engine related
|
||||
// const CustomGraph =require(/*import your Grapg subclass */);
|
||||
|
||||
|
||||
// // Format a triple pattern acccording to N3 API
|
||||
// // SPARQL variables must be replaced by `null` values
|
||||
// function formatTriplePattern (triple){
|
||||
// let subject = null
|
||||
// let predicate = null
|
||||
// let object = null
|
||||
// if (!triple.subject.startWith('?')){
|
||||
// subject = triple.subject
|
||||
// }
|
||||
// if (!triple.predicate.startWith('?')){
|
||||
// predicate = triple.predicate
|
||||
// }
|
||||
// if(!triple.object.startWith('?')){
|
||||
// object = triple.object
|
||||
// }
|
||||
// return { subject, predicate, object}
|
||||
// }
|
||||
//////////////////////END OF SPARQL_ENGINE CODE
|
||||
|
||||
|
||||
// ////////////////sparqle-engine code startred/////////
|
||||
// /**
|
||||
// * the following code is for checking sparql-engine
|
||||
// */
|
||||
|
||||
// // class CustomGraph extends Graph {
|
||||
|
||||
// // /**
|
||||
// // * Returns an iterator that finds RDF triples matching a triple pattern in the graph.
|
||||
// // * @param triple - Triple pattern to find
|
||||
// // * @return An observable which finds RDF triples matching a triple pattern
|
||||
// // */
|
||||
// // find (triple:TripleObject, options: Object): Observable<TripleObject> {/* */}
|
||||
// // }
|
||||
|
||||
// class N3Graph extends Graph {
|
||||
// constructor (){
|
||||
// super()
|
||||
// this._store = store()
|
||||
// }
|
||||
|
||||
// insert (triple){
|
||||
// return new Promise((resolve, reject) => {
|
||||
// try {
|
||||
// this._store.addTriple(triple.subject, triple.predicate, triple.object)
|
||||
// resolve()
|
||||
|
||||
// } catch (e) {
|
||||
// reject (e)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// find (triple) {
|
||||
// const {subject, predicate, object}= formatTriplePattern(triple)
|
||||
// return this._store.getTriple (subject, predicate, object)
|
||||
// }
|
||||
|
||||
// estimateCardinality (triple){
|
||||
// const {subject,predicate,object} = formatTriplePattern(triple)
|
||||
// return Promise.resolve(this._store.countTriples(subject,predicate,object))
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// const graph = new N3Graph()
|
||||
// const dataset = new HashMapDataset ('http://example.org#default', graph)
|
||||
|
||||
// //load some RDF data into the graph
|
||||
// const parser = new Parser()
|
||||
// parser.parse(`
|
||||
// @prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
||||
// @prefic : <http://example.org#> .
|
||||
// :a foaf:name "a" .
|
||||
// :b foaf:name "b" .
|
||||
// `).forEach(t => {graph._store.addTriple(t)
|
||||
// })
|
||||
|
||||
|
||||
// // const GRAPH_A_IRI ='http://example.org#graph-a';
|
||||
// // const GRAPH_B_IRI ='http://example.org#graph-b';
|
||||
// // const graph_a =new CustomGraph(/* */);
|
||||
// // const graph_b = new CustomGraph(/* */);
|
||||
|
||||
// // //we set graph_a as a defualt RDF dataset
|
||||
// // const dataset = new HashMapDataset(GRAPH_A_IRI, graph_a);
|
||||
// // //insert graph_b as a Named Grapg
|
||||
// // dataset.addNamedGraph(GRAPH_B_IRI, graph_b);
|
||||
|
||||
// //Get the Name of all the people in the default Graph
|
||||
// // const query= `
|
||||
// // PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
// // PREFIX foaf: <http://xmlns.com/foaf/0.1>
|
||||
// // SELECT ?name
|
||||
// // WHERE{
|
||||
// // ?s a foaf:Person .
|
||||
// // ?s rdfs:label ?label .
|
||||
// // }`
|
||||
// const query = `
|
||||
// PREFIX foaf: <http://xmlns.com/foaf/0.1/>
|
||||
// SELECT ?name
|
||||
// WHERE {
|
||||
// ?s foaf:name ?name .
|
||||
// }`
|
||||
|
||||
// // Creates a plan builder for the RDF dataset
|
||||
// const builder = new PlanBuilder(dataset);
|
||||
|
||||
// // Get an iterator to evaluate the query
|
||||
// const iterator = builder.build(query);
|
||||
|
||||
// //read results
|
||||
// iterator.subscribe(
|
||||
// binding => console.log(bindings),
|
||||
// err => console.error(err),
|
||||
// () => console.log('Query evaluation complete')
|
||||
// );
|
||||
///////////////////////////////////////////////////////////Integration///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////Integration///////////////////////////////////////////////////////////
|
||||
DistributedBrokers = ["mqtt.eclipse.org", "test.mosquitto.org","broker.hivemq.com"];
|
||||
DistributedBrokersPorts = [1883,1883,1883];
|
||||
function makeTopic(length) {
|
||||
|
|
74
app/miner.js
74
app/miner.js
|
@ -1,63 +1,37 @@
|
|||
const Wallet = require('../wallet');
|
||||
const CoinTransaction = require('../wallet/CoinTransaction');
|
||||
const MetaDataTransaction = require('../wallet/MetaDataTransaction');
|
||||
//const MetaDataPool= require('../wallet/metaData-Pool');
|
||||
const { MaxNumOfCoinTransactions, MaxNumOfMetadataTransactions} = require('../config');
|
||||
var TransactionPointer;
|
||||
var NumberOfClearedCoins;
|
||||
var NumberOfClearedMeta;
|
||||
const Transaction = require('../wallet/transaction');
|
||||
|
||||
|
||||
class Miner {
|
||||
constructor(blockchain, transactionPool, wallet, p2pServer) {
|
||||
this.blockchain = blockchain;
|
||||
this.transactionPool = transactionPool;
|
||||
this.wallet = wallet;
|
||||
this.p2pServer = p2pServer;
|
||||
}
|
||||
}
|
||||
|
||||
mine() {
|
||||
|
||||
//const validCoinTransactions = this.transactionPool.validCoinTransactions(); Temeperarly changed without checking transaction validity
|
||||
var SelectedCoinTransactions = this.transactionPool.cointransactions.slice(0, MaxNumOfCoinTransactions);
|
||||
var SelectedMetadataTransactions = this.transactionPool.metaDataTransactions.slice(0, MaxNumOfMetadataTransactions);
|
||||
//const validTransactions = validCoinTransactions.Concat(validMetaDataTransactions);
|
||||
// SelectedCoinTransactions = validCoinTransactions.splice (0, MaxNumOfCoinTransactions); //this will return only limited number of transactions to be stored
|
||||
// for (TransactionPointer=0; TransactionPointer<MaxNumOfCoinTransactions; TransactionPointer++){
|
||||
// SelectedCoinTransactions.push(validCoinTransactions[TransactionPointer]);
|
||||
// }
|
||||
|
||||
// SelectedMetadataTransactions = validMetadataTransactions.splice (0, MaxNumOfMetadataTransactions);
|
||||
// for (TransactionPointer=0; TransactionPointer<MaxNumOfCoinTransactions; TransactionPointer++){
|
||||
// SelectedCoinTransactions.push(validCoinTransactions[TransactionPointer]);
|
||||
// }
|
||||
// include a reward transaction for the miner
|
||||
SelectedCoinTransactions.push(CoinTransaction.rewardCoinTransaction(this.wallet, Wallet.blockchainWallet()));
|
||||
//CoinTransaction.rewardCoinTransaction(this.wallet, Wallet.blockchainWallet()));
|
||||
// create a block consisting of the valid transactions
|
||||
const block = this.blockchain.addBlock([SelectedCoinTransactions,SelectedMetadataTransactions]);
|
||||
//const block = this.blockchain.addBlock(validTransactions);
|
||||
// synchronize chains in the peer-to-peer server
|
||||
|
||||
|
||||
this.p2pServer.syncChains();
|
||||
|
||||
// clear the transaction pool
|
||||
// broadcast to every miner to clear their transaction pools
|
||||
// if (validCoinTransactions.length>MaxNumOfCoinTransactions){
|
||||
// this.transactionPool.clearCoin();// clears only selected cointransactions
|
||||
|
||||
this.transactionPool.clearCoin(SelectedCoinTransactions.length-1);
|
||||
this.transactionPool.clearMeta(SelectedMetadataTransactions.length);
|
||||
this.p2pServer.broadcastClearCoinTransactions();
|
||||
this.p2pServer.broadcastClearMetadataTransactions();
|
||||
SelectedCoinTransactions = [];
|
||||
SelectedMetadataTransactions =[];
|
||||
// }
|
||||
// else {
|
||||
// this.transactionPool.clearAll();
|
||||
// this.p2pServer.broadcastClearAllTransactions();
|
||||
const validTransactions = this.transactionPool.validTransactions();
|
||||
validTransactions.push(
|
||||
Transaction.rewardTransaction(this.wallet, Wallet.blockchainWallet())
|
||||
);
|
||||
console.log(validTransactions);
|
||||
console.log("//////");
|
||||
const validMetadataS = this.transactionPool.validMetadataS();
|
||||
// for (let i =0; i <validMetadataS.length; i++){
|
||||
// validTransactions.push(validMetadataS[i]);
|
||||
// }
|
||||
|
||||
console.log(validTransactions);
|
||||
// const validMetadataS = this.transactionPool.metadataS;
|
||||
const block = this.blockchain.addBlock([validTransactions, validMetadataS]);
|
||||
this.p2pServer.syncChains();
|
||||
this.transactionPool.clear();
|
||||
this.p2pServer.broadcastClearTransactions();
|
||||
|
||||
return block;
|
||||
}
|
||||
}
|
||||
//module.exports = {NumberOfClearedCoins, NumberOfClearedMeta};
|
||||
module.exports = Miner;
|
||||
|
||||
module.exports = Miner;
|
||||
|
||||
|
|
|
@ -1,124 +1,104 @@
|
|||
const Websocket = require('ws');
|
||||
const P2P_PORT = process.env.P2P_PORT || 5001;
|
||||
|
||||
const P2P_PORT = process.env.P2P_PORT || 5000;
|
||||
const peers = process.env.PEERS ? process.env.PEERS.split(',') : [];
|
||||
const MESSAGE_TYPES = {
|
||||
chain: 'CHAIN',
|
||||
cointransaction: 'COINTRANSACTION',
|
||||
clear_payment_transactions: 'CLEAR_Payment_TRANSACTIONS',
|
||||
clear_meta_transactions: 'CLEAR_META_TRANSACTIONS',
|
||||
clear_Comp_transactions: 'CLEAR_COMP_TRANSACTIONS',
|
||||
clear_Integration_transactions: 'CLEAR_Integration_TRANSACTIONS',
|
||||
metaDataTransaction: 'METADATATRANSACTION',};
|
||||
transaction: 'TRANSACTION',
|
||||
clear_transactions: 'CLEAR_TRANSACTIONS',
|
||||
metadata: 'METADATA'
|
||||
};
|
||||
|
||||
class P2pServer {
|
||||
constructor(blockchain, transactionPool) {
|
||||
this.blockchain = blockchain;
|
||||
this.transactionPool = transactionPool;
|
||||
this.sockets = [];}
|
||||
this.sockets = [];
|
||||
}
|
||||
|
||||
listen() {
|
||||
const server = new Websocket.Server({ port: P2P_PORT });
|
||||
server.on('connection', socket => this.connectSocket(socket));
|
||||
|
||||
this.connectToPeers();
|
||||
console.log(`Listening for peer-to-peer connections on: ${P2P_PORT}`);}
|
||||
connectToPeers() {
|
||||
|
||||
console.log(`Listening for peer-to-peer connections on: ${P2P_PORT}`);
|
||||
}
|
||||
|
||||
connectToPeers() {
|
||||
peers.forEach(peer => {
|
||||
const socket = new Websocket(peer);
|
||||
socket.on('open', () => this.connectSocket(socket)); });}
|
||||
|
||||
socket.on('open', () => this.connectSocket(socket));
|
||||
});
|
||||
}
|
||||
|
||||
connectSocket(socket) {
|
||||
this.sockets.push(socket);
|
||||
console.log('Socket connected');
|
||||
|
||||
this.messageHandler(socket);
|
||||
this.sendChain(socket);}
|
||||
messageHandler(socket) {
|
||||
|
||||
this.sendChain(socket);
|
||||
}
|
||||
|
||||
messageHandler(socket) {
|
||||
socket.on('message', message => {
|
||||
const data = JSON.parse(message);
|
||||
switch(data.type) {
|
||||
case MESSAGE_TYPES.chain:
|
||||
this.blockchain.replaceChain(data.chain);
|
||||
break;
|
||||
case MESSAGE_TYPES.paymenttransaction:
|
||||
this.transactionPool.updateOrAddPaymentTransaction(
|
||||
data.Paymenttransaction);
|
||||
case MESSAGE_TYPES.transaction:
|
||||
this.transactionPool.updateOrAddTransaction(data.transaction);
|
||||
break;
|
||||
case MESSAGE_TYPES.metaDataTransaction:
|
||||
this.transactionPool.updateOrAddMetaDataTransaction(
|
||||
data.metaDataTransaction);
|
||||
break;
|
||||
case MESSAGE_TYPES.CompTransaction:
|
||||
this.transactionPool.updateOrAddCompTransaction(
|
||||
data.CompTransaction);
|
||||
break;
|
||||
case MESSAGE_TYPES.IntegrationTransaction:
|
||||
this.transactionPool.updateOrAddIntegrationTransaction(
|
||||
data.IntegrationTransaction);
|
||||
break;
|
||||
case MESSAGE_TYPES.clear_Payment_transactions:
|
||||
this.transactionPool.clearPayment(this.blockchain.chain[this.
|
||||
blockchain.chain.length-1].data[0].length-1);
|
||||
case MESSAGE_TYPES.metadata:
|
||||
this.transactionPool.updateOrAddMetadata(data.metadata);
|
||||
break;
|
||||
case MESSAGE_TYPES.clear_meta_transactions:
|
||||
this.transactionPool.clearMeta(this.blockchain.chain[this.
|
||||
blockchain.chain.length-1].data[1].length);
|
||||
case MESSAGE_TYPES.clear_transactions:
|
||||
this.transactionPool.clear();
|
||||
break;
|
||||
case MESSAGE_TYPES.clear_comp_transactions:
|
||||
this.transactionPool.clearMeta(this.blockchain.chain[this.
|
||||
blockchain.chain.length-1].data[1].length);
|
||||
break;
|
||||
case MESSAGE_TYPES.clear_intgration_transactions:
|
||||
this.transactionPool.clearMeta(this.blockchain.chain[this.
|
||||
blockchain.chain.length-1].data[1].length);
|
||||
break;}});}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendChain(socket) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.chain,
|
||||
chain: this.blockchain.chain}));}
|
||||
ClearedPayments (socket){
|
||||
chain: this.blockchain.chain
|
||||
}));
|
||||
}
|
||||
|
||||
sendTransaction(socket, transaction) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.clear_payment_transactions,})); }
|
||||
ClearedMeta (socket){
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.clear_meta_transactions,}));}
|
||||
ClearedComp (socket){
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.clear_comp_transactions,}));}
|
||||
ClearedIntegration (socket){
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.clear_integration_transactions,}));}
|
||||
sendPaymentTransaction(socket, paymenttransaction) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.paymenttransaction,
|
||||
paymenttransaction}));}
|
||||
sendMetaDataTransaction(socket, metaDataTransaction) {
|
||||
type: MESSAGE_TYPES.transaction,
|
||||
transaction
|
||||
}));
|
||||
}
|
||||
|
||||
sendMetadata(socket, metadata) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.metaDataTransaction,
|
||||
metaDataTransaction}));}
|
||||
sendIntegrationTransaction(socket, integrationTransaction) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.integrationTransaction,
|
||||
integrationTransaction}));}
|
||||
sendCompTransaction(socket, compTransaction) {
|
||||
socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.compTransaction,
|
||||
compTransaction}));}
|
||||
type: MESSAGE_TYPES.metadata,
|
||||
metadata
|
||||
}));
|
||||
}
|
||||
syncChains() {
|
||||
this.sockets.forEach(socket => this.sendChain(socket));}
|
||||
broadcastPaymentTransaction(paymenttransaction) {
|
||||
this.sockets.forEach(socket => this.sendPaymentTransaction(socket,
|
||||
paymenttransaction));}
|
||||
broadcastMetaDataTransaction(metaDataTransaction) {
|
||||
this.sockets.forEach(socket => this.sendMetaDataTransaction(socket,
|
||||
metaDataTransaction));}
|
||||
broadcastCompTransaction(compTransaction) {
|
||||
this.sockets.forEach(socket => this.sendCompTransaction(socket,
|
||||
CompTransaction));}
|
||||
broadcastIntegrationTransaction(integrationTransaction) {
|
||||
this.sockets.forEach(socket => this.sendIntegrationTransaction(socket,
|
||||
integrationTransaction));}
|
||||
broadcastClearPaymentTransactions() {
|
||||
this.sockets.forEach(socket => this.ClearedCoins(socket));}
|
||||
broadcastClearMetadataTransactions() {
|
||||
this.sockets.forEach(socket => this.ClearedMeta(socket));}
|
||||
broadcastClearCompTransactions() {
|
||||
this.sockets.forEach(socket => this.ClearedComp(socket));}
|
||||
broadcastClearIntegrationTransactions() {
|
||||
this.sockets.forEach(socket => this.ClearedIntegration(socket));}}
|
||||
module.exports = P2pServer ;
|
||||
this.sockets.forEach(socket => this.sendChain(socket));
|
||||
}
|
||||
|
||||
broadcastTransaction(transaction) {
|
||||
this.sockets.forEach(socket => this.sendTransaction(socket, transaction));
|
||||
}
|
||||
|
||||
broadcastMetadata(metadata) {
|
||||
this.sockets.forEach(socket => this.sendMetadata(socket, metadata));
|
||||
}
|
||||
|
||||
broadcastClearTransactions() {
|
||||
this.sockets.forEach(socket => socket.send(JSON.stringify({
|
||||
type: MESSAGE_TYPES.clear_transactions
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = P2pServer;
|
|
@ -1,6 +0,0 @@
|
|||
const swaggerAutogen = require('swagger-autogen')()
|
||||
|
||||
const outputFile = './swagger_output.json'
|
||||
const APIfiles = ['./index.js']
|
||||
|
||||
swaggerAutogen(outputFile, APIfiles)
|
|
@ -1,369 +0,0 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "REST API",
|
||||
"description": ""
|
||||
},
|
||||
"host": "localhost:3000",
|
||||
"basePath": "/",
|
||||
"schemes": [
|
||||
"http"
|
||||
],
|
||||
"paths": {
|
||||
"/blocks": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/MetaDataTransactions": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/CoinTransactions": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/Transactions": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mine-transactions": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/public-key": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/Balance": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/mine": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/IoTdeviceRegistration": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Name": {
|
||||
"example": "any"
|
||||
},
|
||||
"Geo": {
|
||||
"example": "any"
|
||||
},
|
||||
"IP_URL": {
|
||||
"example": "any"
|
||||
},
|
||||
"Topic_Token": {
|
||||
"example": "any"
|
||||
},
|
||||
"Permission": {
|
||||
"example": "any"
|
||||
},
|
||||
"RequestDetail": {
|
||||
"example": "any"
|
||||
},
|
||||
"OrgOwner": {
|
||||
"example": "any"
|
||||
},
|
||||
"DepOwner": {
|
||||
"example": "any"
|
||||
},
|
||||
"PrsnOwner": {
|
||||
"example": "any"
|
||||
},
|
||||
"PaymentPerKbyte": {
|
||||
"example": "any"
|
||||
},
|
||||
"PaymentPerMinute": {
|
||||
"example": "any"
|
||||
},
|
||||
"Protocol": {
|
||||
"example": "any"
|
||||
},
|
||||
"MessageAttributes": {
|
||||
"example": "any"
|
||||
},
|
||||
"Interval": {
|
||||
"example": "any"
|
||||
},
|
||||
"FurtherDetails": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/IoTdevicePaymentTransaction": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Recipient_payment_address": {
|
||||
"example": "any"
|
||||
},
|
||||
"Amount_of_money": {
|
||||
"example": "any"
|
||||
},
|
||||
"Payment_method": {
|
||||
"example": "any"
|
||||
},
|
||||
"Further_details": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/UploadMetafile": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"201": {
|
||||
"description": "Created"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/selectedMeta": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Name": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/sparql": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Select": {
|
||||
"example": "any"
|
||||
},
|
||||
"subject": {
|
||||
"example": "any"
|
||||
},
|
||||
"predicate": {
|
||||
"example": "any"
|
||||
},
|
||||
"object": {
|
||||
"example": "any"
|
||||
},
|
||||
"Limit": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/sparql2": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Select": {
|
||||
"example": "any"
|
||||
},
|
||||
"subject": {
|
||||
"example": "any"
|
||||
},
|
||||
"predicate": {
|
||||
"example": "any"
|
||||
},
|
||||
"object": {
|
||||
"example": "any"
|
||||
},
|
||||
"Limit": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/IoTdeviceIntegration-Control": {
|
||||
"post": {
|
||||
"description": "",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"IoTDeviceID": {
|
||||
"example": "any"
|
||||
},
|
||||
"paymentTransactionID": {
|
||||
"example": "any"
|
||||
},
|
||||
"Duration": {
|
||||
"example": "any"
|
||||
},
|
||||
"Protocol": {
|
||||
"example": "any"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/IoTdataObtainingAndForward": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,52 +2,54 @@ const ChainUtil = require('../chain-util');
|
|||
const { DIFFICULTY, MINE_RATE } = require('../config');
|
||||
|
||||
class Block {
|
||||
constructor(timestamp,BlockNum, lastHash, hash, data, nonce,
|
||||
difficulty) {
|
||||
constructor(timestamp, lastHash, hash, data, nonce, difficulty) {
|
||||
this.timestamp = timestamp;
|
||||
this.BlockNum = BlockNum;
|
||||
this.lastHash = lastHash;
|
||||
this.hash = hash;
|
||||
this.data = data;
|
||||
this.nonce = nonce;
|
||||
this.difficulty = difficulty || DIFFICULTY;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `Block -
|
||||
Timestamp : ${this.timestamp}
|
||||
BlockNum : ${this.BlockNum}
|
||||
Last Hash : ${this.lastHash.substring(0, 10)}
|
||||
Hash : ${this.hash.substring(0, 10)}
|
||||
Nonce : ${this.nonce}
|
||||
Difficulty: ${this.difficulty}
|
||||
Data : ${this.data[0].length}`;
|
||||
Data : ${this.data}`;
|
||||
}
|
||||
|
||||
static genesis() {
|
||||
return new this('Genesis-time',0, '-----', 'First-Hash',
|
||||
[], 0, DIFFICULTY);
|
||||
return new this('Genesis time', '-----', 'f1r57-h45h', [], 0, DIFFICULTY);
|
||||
}
|
||||
|
||||
static mineBlock(lastBlock, data) {
|
||||
let hash, timestamp;
|
||||
const lastHash = lastBlock.hash;
|
||||
let { difficulty } = lastBlock;
|
||||
let nonce = 0;
|
||||
let BlockNum = lastBlock.BlockNum + 1;
|
||||
|
||||
do {
|
||||
nonce++;
|
||||
timestamp = Date.now();
|
||||
difficulty = Block.adjustDifficulty(lastBlock, timestamp);
|
||||
hash = Block.hash(timestamp, lastHash, data, nonce, difficulty);
|
||||
} while (hash.substring(0, difficulty) !== '0'.repeat(difficulty));
|
||||
return new this(timestamp,BlockNum, lastHash, hash, data, nonce,
|
||||
difficulty);}
|
||||
static hash(timestamp,lastHash, data, nonce, difficulty) {
|
||||
return ChainUtil.hash(`${timestamp}${lastHash}${data}${nonce}
|
||||
${difficulty}`).toString();
|
||||
|
||||
return new this(timestamp, lastHash, hash, data, nonce, difficulty);
|
||||
}
|
||||
|
||||
static hash(timestamp, lastHash, data, nonce, difficulty) {
|
||||
return ChainUtil.hash(`${timestamp}${lastHash}${data}${nonce}${difficulty}`).toString();
|
||||
}
|
||||
|
||||
static blockHash(block) {
|
||||
const { timestamp, lastHash, data, nonce, difficulty } = block;
|
||||
return Block.hash(timestamp, lastHash, data, nonce, difficulty);
|
||||
}
|
||||
|
||||
static adjustDifficulty(lastBlock, currentTime) {
|
||||
let { difficulty } = lastBlock;
|
||||
difficulty = lastBlock.timestamp + MINE_RATE > currentTime ?
|
||||
|
@ -55,4 +57,5 @@ class Block {
|
|||
return difficulty;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Block;
|
296
blocks.json
296
blocks.json
|
@ -1,296 +0,0 @@
|
|||
Block -
|
||||
Timestamp : 1581892713022
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000f64170
|
||||
Nonce : 94889
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892714610
|
||||
Last Hash : 0000f64170
|
||||
Hash : 000001941a
|
||||
Nonce : 121452
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892736795
|
||||
Last Hash : 000004bdbe
|
||||
Hash : 0000af3e65
|
||||
Nonce : 1109949
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892725766
|
||||
Last Hash : 00001402a6
|
||||
Hash : 000004bdbe
|
||||
Nonce : 114910
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892752249
|
||||
Last Hash : 0000145513
|
||||
Hash : 0000085224
|
||||
Nonce : 484976
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892762535
|
||||
Last Hash : 0000085224
|
||||
Hash : 00001cd286
|
||||
Nonce : 995419
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892763338
|
||||
Last Hash : 00001cd286
|
||||
Hash : 00000c8fa5
|
||||
Nonce : 80136
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892724628
|
||||
Last Hash : 000001941a
|
||||
Hash : 00001402a6
|
||||
Nonce : 964391
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892746837
|
||||
Last Hash : 0000af3e65
|
||||
Hash : 0005cb06ba
|
||||
Nonce : 960133
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581892747191
|
||||
Last Hash : 0005cb06ba
|
||||
Hash : 0000145513
|
||||
Nonce : 35175
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894328935
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000027b9b
|
||||
Nonce : 41326
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894353562
|
||||
Last Hash : 00084950c6
|
||||
Hash : 0000cc1d6a
|
||||
Nonce : 16931
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894360160
|
||||
Last Hash : 0000cc1d6a
|
||||
Hash : 00000a55b4
|
||||
Nonce : 681141
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894370451
|
||||
Last Hash : 00000a55b4
|
||||
Hash : 000062a73f
|
||||
Nonce : 1065366
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894372244
|
||||
Last Hash : 000062a73f
|
||||
Hash : 000006be7e
|
||||
Nonce : 182919
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894383168
|
||||
Last Hash : 000006be7e
|
||||
Hash : 0000947649
|
||||
Nonce : 1129947
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894385832
|
||||
Last Hash : 0000947649
|
||||
Hash : 0000063c81
|
||||
Nonce : 274322
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894339035
|
||||
Last Hash : 0000027b9b
|
||||
Hash : 0007a1423c
|
||||
Nonce : 995688
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894343276
|
||||
Last Hash : 0007a1423c
|
||||
Hash : 00008d4e58
|
||||
Nonce : 379871
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581894353389
|
||||
Last Hash : 00008d4e58
|
||||
Hash : 00084950c6
|
||||
Nonce : 1043732
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914042391
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 00005dbdc7
|
||||
Nonce : 16289
|
||||
Difficulty: 4
|
||||
Data : [object Object],[object Object],[object Object]
|
||||
Block -
|
||||
Timestamp : 1581914052481
|
||||
Last Hash : 00005dbdc7
|
||||
Hash : 0002715612
|
||||
Nonce : 945209
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914052947
|
||||
Last Hash : 0002715612
|
||||
Hash : 00006f867b
|
||||
Nonce : 44547
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914073313
|
||||
Last Hash : 0002826b45
|
||||
Hash : 0000595eff
|
||||
Nonce : 7524
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914083348
|
||||
Last Hash : 0000595eff
|
||||
Hash : 000387395e
|
||||
Nonce : 974338
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914083523
|
||||
Last Hash : 000387395e
|
||||
Hash : 0000d7ada9
|
||||
Nonce : 15912
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914091333
|
||||
Last Hash : 0000d7ada9
|
||||
Hash : 00000ce8de
|
||||
Nonce : 733896
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914063218
|
||||
Last Hash : 000873faba
|
||||
Hash : 0000c9a5a8
|
||||
Nonce : 23871
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914073229
|
||||
Last Hash : 0000c9a5a8
|
||||
Hash : 0002826b45
|
||||
Nonce : 1004347
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914062966
|
||||
Last Hash : 00006f867b
|
||||
Hash : 000873faba
|
||||
Nonce : 964936
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914568417
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000646876
|
||||
Nonce : 8365
|
||||
Difficulty: 4
|
||||
Data : [object Object],[object Object],[object Object]
|
||||
Block -
|
||||
Timestamp : 1581914578440
|
||||
Last Hash : 0000646876
|
||||
Hash : 00034edf74
|
||||
Nonce : 948376
|
||||
Difficulty: 3
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914579386
|
||||
Last Hash : 00034edf74
|
||||
Hash : 00003f7371
|
||||
Nonce : 88529
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914847561
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000a45f66
|
||||
Nonce : 58810
|
||||
Difficulty: 4
|
||||
Data : [object Object],[object Object]
|
||||
Block -
|
||||
Timestamp : 1581914850074
|
||||
Last Hash : 0000a45f66
|
||||
Hash : 0000053121
|
||||
Nonce : 229566
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581914860093
|
||||
Last Hash : 0000053121
|
||||
Hash : 0000f0fa54
|
||||
Nonce : 968591
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581915028382
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 000012342d
|
||||
Nonce : 74682
|
||||
Difficulty: 4
|
||||
Data : [object Object],[object Object]
|
||||
Block -
|
||||
Timestamp : 1581915029059
|
||||
Last Hash : 000012342d
|
||||
Hash : 000009fa64
|
||||
Nonce : 59238
|
||||
Difficulty: 5
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1581915039087
|
||||
Last Hash : 000009fa64
|
||||
Hash : 0000219469
|
||||
Nonce : 963908
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1631336762365
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000cb4fc4
|
||||
Nonce : 87088
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Mined Block
|
||||
Block -
|
||||
Timestamp : 1631336852594
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000fa68c7
|
||||
Nonce : 31088
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Block -
|
||||
Timestamp : 1631337166316
|
||||
Last Hash : f1r57-h45h
|
||||
Hash : 0000b73e4b
|
||||
Nonce : 31185
|
||||
Difficulty: 4
|
||||
Data : [object Object],
|
||||
Mined Block
|
|
@ -1,6 +1,6 @@
|
|||
const EC = require('elliptic').ec;
|
||||
const SHA256 = require('crypto-js/sha256');
|
||||
const uuidV1 = require('uuid/v1');
|
||||
const { v1 : uuidV1 } = require ('uuid');
|
||||
const ec = new EC('secp256k1');
|
||||
|
||||
class ChainUtil {
|
||||
|
|
12
config.js
12
config.js
|
@ -1,8 +1,6 @@
|
|||
const DIFFICULTY = 5;
|
||||
const MINE_RATE = 20000;
|
||||
const INITIAL_BALANCE = 500;
|
||||
const MINING_REWARD = 50;
|
||||
const MaxNumOfCoinTransactions = 3;
|
||||
const MaxNumOfMetadataTransactions = 3;
|
||||
const DIFFICULTY = 3;
|
||||
const MINE_RATE = 3000;
|
||||
const INITIAL_BALANCE = 500;
|
||||
const MINING_REWARD = 50;
|
||||
|
||||
module.exports = { DIFFICULTY, MINE_RATE, INITIAL_BALANCE, MINING_REWARD, MaxNumOfCoinTransactions, MaxNumOfMetadataTransactions} ;
|
||||
module.exports = { DIFFICULTY, MINE_RATE, INITIAL_BALANCE, MINING_REWARD };
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"MONGO_ATLAS_PW":"11112222-m"
|
||||
}
|
||||
}
|
25145
package-lock.json
generated
25145
package-lock.json
generated
File diff suppressed because it is too large
Load diff
46
package.json
46
package.json
|
@ -1,55 +1,37 @@
|
|||
{
|
||||
"name": "Sen-Sha-Mart",
|
||||
"version": "6.0.0",
|
||||
"name": "senshamartproject",
|
||||
"version": "1.0.0",
|
||||
"description": "A novel Marketplace for sharing sensors in decentralized environment",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "jest --watchAll",
|
||||
"dev-test": "nodemon dev-test",
|
||||
"start": "node ./app",
|
||||
"dev": "nodemon ./app",
|
||||
"sparql": "nodemon ./test/comunicaSPARQL",
|
||||
"jsonld": "nodemon ./test/jsonld",
|
||||
"sparqlEngine": "nodemon ./test/sparqlEngine",
|
||||
"N3": "nodemon ./test/N3sudo yarn ",
|
||||
"swagger-autogen": "node ./app/swagger.js"
|
||||
"dev": "nodemon ./app"
|
||||
},
|
||||
"jest": {
|
||||
"testEnvironment": "node"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "AnasDawod",
|
||||
"author": "Anas Dawod",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"jest": "^22.1.4",
|
||||
"nodemon": "^1.14.12",
|
||||
"swagger-autogen": "^2.22.0"
|
||||
"jest": "^29.2.0",
|
||||
"jest-cli": "^29.2.0",
|
||||
"nodemon": "^2.0.20"
|
||||
},
|
||||
"dependencies": {
|
||||
"@comunica/actor-init-sparql": "^1.9.1",
|
||||
"@comunica/actor-init-sparql-file": "^1.9.1",
|
||||
"@comunica/actor-init-sparql-rdfjs": "^1.9.1",
|
||||
"@comunica/query-sparql": "^2.5.2",
|
||||
"aedes": "^0.42.5",
|
||||
"body-parser": "^1.18.2",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"elliptic": "^6.4.0",
|
||||
"express": "^4.16.2",
|
||||
"http": "0.0.0",
|
||||
"body-parser": "^1.20.1",
|
||||
"crypto-js": "^4.1.1",
|
||||
"elliptic": "^6.5.4",
|
||||
"express": "^4.18.2",
|
||||
"jsonld": "^1.7.0",
|
||||
"level": "^5.0.1",
|
||||
"level-browserify": "^2.0.0",
|
||||
"levelgraph": "^2.1.1",
|
||||
"lodash": "^4.17.11",
|
||||
"log4js": "^6.1.2",
|
||||
"morgan": "^1.9.1",
|
||||
"mosca": "^2.8.3",
|
||||
"mqtt": "^4.1.0",
|
||||
"multer": "^1.3.1",
|
||||
"n3": "^1.2.0",
|
||||
"sparql-engine": "^0.5.3",
|
||||
"stream": "^0.0.2",
|
||||
"swagger-ui-express": "^4.5.0",
|
||||
"uuid": "^3.2.1",
|
||||
"ws": "^4.0.0"
|
||||
"uuid": "^9.0.0",
|
||||
"ws": "^8.9.0"
|
||||
}
|
||||
}
|
||||
|
|
BIN
test/.DS_Store
vendored
BIN
test/.DS_Store
vendored
Binary file not shown.
|
@ -1,49 +0,0 @@
|
|||
const N3 = require('n3');
|
||||
const newEngine = require('@comunica/actor-init-sparql-rdfjs').newEngine;
|
||||
const jsonld = require('jsonld');
|
||||
const N3Store = require('n3').Store;
|
||||
const DataFactory = require('n3').DataFactory;
|
||||
|
||||
|
||||
|
||||
const myEngine = newEngine();
|
||||
const parser = new N3.Parser();
|
||||
const store = new N3Store();
|
||||
|
||||
const doc = {
|
||||
"http://schema.org/name": "Manu Sporny",
|
||||
"http://schema.org/url": {"@id": "http://manu.sporny.org/"},
|
||||
"http://schema.org/image": {"@id": "http://manu.sporny.org/images/manu.png"}
|
||||
};
|
||||
|
||||
|
||||
jsonld.toRDF(doc, {format: 'application/n-quads'}, (err, nquads) => {
|
||||
// nquads is a string of N-Quads
|
||||
//console.log(nquads);
|
||||
|
||||
|
||||
parser.parse(
|
||||
nquads,
|
||||
(error, quad, prefixes) => {
|
||||
if (quad)
|
||||
//console.log(quad);
|
||||
store.addQuad(quad);
|
||||
else
|
||||
console.log(store);
|
||||
|
||||
const start = async function (a,b){
|
||||
const result = await myEngine.query('SELECT * { ?s ?p <http://manu.sporny.org/>. ?s ?p ?o} LIMIT 100',
|
||||
{ sources: [ { value: store } ] });
|
||||
//result.bindingsStream.on('data', (data) => {
|
||||
// Each data object contains a mapping from variables to RDFJS terms.
|
||||
console.log(result);
|
||||
// console.log(data.get('?p'));
|
||||
// console.log(data.get('?o'));
|
||||
// });
|
||||
};
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
|
||||
});
|
|
@ -1,68 +0,0 @@
|
|||
const newEngine = require('@comunica/actor-init-sparql').newEngine;
|
||||
const N3 = require('n3');
|
||||
const jsonld = require('jsonld')
|
||||
const DataFactory = require('n3').DataFactory;
|
||||
const parser = new N3.Parser({format: 'application/n-quads'});
|
||||
|
||||
const store = new N3.Store();
|
||||
const myEngine = newEngine();
|
||||
|
||||
const doc = {
|
||||
"http://schema.org/name": "Manu Sporny",
|
||||
"http://schema.org/url": {"@id": "http://manu.sporny.org/"},
|
||||
"http://schema.org/image": {"@id": "http://manu.sporny.org/images/manu.png"}
|
||||
};
|
||||
|
||||
jsonld.toRDF(doc, {format: 'application/n-quads'}, (err, nquads) => {
|
||||
// nquads is a string of N-Quads
|
||||
// console.log(nquads);
|
||||
var quad= [];
|
||||
parser.parse(
|
||||
nquads,
|
||||
(error, quadN, prefixes) => {
|
||||
// console.log(quadN)
|
||||
if (quadN)
|
||||
{
|
||||
store.addQuad(DataFactory.quad(
|
||||
DataFactory.namedNode(quadN.subject.id), DataFactory.namedNode(quadN.predicate.id), DataFactory.namedNode(quadN.object.id)));
|
||||
|
||||
}
|
||||
else
|
||||
console.log("finished");
|
||||
// console.log(quadN)
|
||||
});
|
||||
|
||||
const start = async function (a,b){
|
||||
const result = await myEngine.query('SELECT * WHERE {?s ?p ?o } LIMIT 100',
|
||||
{ sources: [{ type: 'rdfjsSource', value: store}] })
|
||||
result.bindingsStream.on('data', (data) => console.log(data.toObject()));
|
||||
};
|
||||
start()
|
||||
console.log(quad)
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode(quad.subject.id), DataFactory.namedNode(quad.predicate.id), DataFactory.namedNode(quad.object.id)));
|
||||
|
||||
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode('http://schema.org/image'), DataFactory.namedNode('http://manu.sporny.org/images/manu.png'), DataFactory.namedNode('http://schema.org/name')));
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode('http://schema.org/url'), DataFactory.namedNode('http://manu.sporny.org/'), DataFactory.namedNode('http://dbpedia.org/resource/Ghent')));
|
||||
//console.log(store)
|
||||
// const start = async function (a,b){
|
||||
// const result = await myEngine.query('SELECT * WHERE {?s ?p <http://manu.sporny.org/images/manu.png>. ?s ?p ?o } LIMIT 100',
|
||||
// { sources: [{ type: 'rdfjsSource', value: store}] })
|
||||
// result.bindingsStream.on('data', (data) => console.log(data.toObject()));
|
||||
// };
|
||||
// start()
|
||||
});
|
||||
|
||||
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode('http://schema.org/image'), DataFactory.namedNode('http://manu.sporny.org/images/manu.png'), DataFactory.namedNode('http://schema.org/name')));
|
||||
// store.addQuad(DataFactory.quad(
|
||||
// DataFactory.namedNode('http://schema.org/url'), DataFactory.namedNode('http://manu.sporny.org/'), DataFactory.namedNode('http://dbpedia.org/resource/Ghent')));
|
||||
|
||||
// // console.log(store)
|
||||
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
const jsonld = require('jsonld');
|
||||
|
||||
const doc = {
|
||||
"http://schema.org/name": "Manu Sporny",
|
||||
"http://schema.org/url": {"@id": "http://manu.sporny.org/"},
|
||||
"http://schema.org/PrsnOwner": "0400985d4fca84fe0e8cff7e8902326a6703ba182cc8d6d8e20866b0acfc79ecb6bfd3d3b5d6ad7f48cd10fadc6d4348cab918f13db2ebb387ba16c57802bf47b1",
|
||||
|
||||
};
|
||||
|
||||
|
||||
jsonld.toRDF(doc, {format: 'application/n-quads'}, (err, nquads) => {
|
||||
// nquads is a string of N-Quads
|
||||
console.log(nquads);
|
||||
|
||||
});
|
||||
// const start = async function (a,b){
|
||||
// const rdf = await jsonld.toRDF(doc, {format: 'application/n-quads'});
|
||||
// console.log(rdf);
|
||||
// };
|
||||
// start();
|
|
@ -1,78 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const { BindingBase, HashMapDataset, Graph, PlanBuilder } = require('sparql-engine')
|
||||
const level = require('level')
|
||||
const levelgraph = require('levelgraph')
|
||||
const { Transform } = require('stream')
|
||||
|
||||
// An utility class used to convert LevelGraph bindings
|
||||
// into a format undestood by sparql-engine
|
||||
class FormatterStream extends Transform {
|
||||
constructor () {
|
||||
super({objectMode: true})
|
||||
}
|
||||
|
||||
_transform (item, encoding, callback) {
|
||||
// Transform LevelGraph objects into set of mappings
|
||||
// using BindingBase.fromObject
|
||||
this.push(BindingBase.fromObject(item))
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
class LevelRDFGraph extends Graph {
|
||||
constructor (db) {
|
||||
super()
|
||||
this._db = db
|
||||
}
|
||||
|
||||
evalBGP (bgp) {
|
||||
// rewrite variables using levelgraph API
|
||||
bgp = bgp.map(t => {
|
||||
if (t.subject.startsWith('?')) {
|
||||
t.subject = this._db.v(t.subject.substring(1))
|
||||
}
|
||||
if (t.predicate.startsWith('?')) {
|
||||
t.predicate = this._db.v(t.predicate.substring(1))
|
||||
}
|
||||
if (t.object.startsWith('?')) {
|
||||
t.object = this._db.v(t.object.substring(1))
|
||||
}
|
||||
return t
|
||||
})
|
||||
// Transform the Stream returned by LevelGraph into an Stream of Bindings
|
||||
return new FormatterStream(this._db.searchStream(bgp))
|
||||
}
|
||||
}
|
||||
|
||||
const db = levelgraph(level('testing_db'))
|
||||
|
||||
// insert some triples
|
||||
var triple1 = { subject: 'http://example.org#a1', predicate: 'http://xmlns.com/foaf/0.1/name', object: '"c"' }
|
||||
var triple2 = { subject: 'http://example.org#a2', predicate: 'http://xmlns.com/foaf/0.1/name', object: '"d"' }
|
||||
db.put([triple1, triple2], () => {
|
||||
const graph = new LevelRDFGraph(db)
|
||||
const dataset = new HashMapDataset('http://example.org#default', graph)
|
||||
|
||||
const query = `
|
||||
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
|
||||
SELECT ?name
|
||||
WHERE {
|
||||
?s foaf:name ?name .
|
||||
}`
|
||||
|
||||
// Creates a plan builder for the RDF dataset
|
||||
const builder = new PlanBuilder(dataset)
|
||||
|
||||
// Get an iterator to evaluate the query
|
||||
const iterator = builder.build(query)
|
||||
|
||||
// Read results
|
||||
iterator.subscribe(bindings => {
|
||||
console.log('Find solutions:', bindings.toObject())
|
||||
}, err => {
|
||||
console.error('error', err)
|
||||
}, () => {
|
||||
console.log('Query evaluation complete!')
|
||||
})
|
||||
})
|
793
uploads/DHT11 and arduino example.json
Normal file
793
uploads/DHT11 and arduino example.json
Normal file
|
@ -0,0 +1,793 @@
|
|||
[ {
|
||||
"@id" : "_:genid1",
|
||||
"@type" : [ "http://xmlns.com/foaf/0.1/Agent" ],
|
||||
"http://xmlns.com/foaf/0.1/name" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "W3C/OGC Spatial Data on the Web Working Group"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "_:genid2",
|
||||
"@type" : [ "http://www.w3.org/ns/sosa/QuantityValue" ]
|
||||
}, {
|
||||
"@id" : "_:genid3",
|
||||
"@type" : [ "http://www.w3.org/2006/time#TemporalEntity" ]
|
||||
}, {
|
||||
"@id" : "_:genid4",
|
||||
"@type" : [ "http://xmlns.com/foaf/0.1/Agent" ],
|
||||
"http://xmlns.com/foaf/0.1/name" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "W3C/OGC Spatial Data on the Web Working Group"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "_:genid5",
|
||||
"@type" : [ "http://xmlns.com/foaf/0.1/Agent" ],
|
||||
"http://xmlns.com/foaf/0.1/name" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "W3C/OGC Spatial Data on the Web Working Group"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://example.org/data/Observation/346344",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Observation" ],
|
||||
"http://www.w3.org/ns/sosa/hasFeatureOfInterest" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'Office_temperature'"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/madeBySensor" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'DHT11'"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/observedProperty" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_temperature'"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://example.org/data/Observation/346345",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Observation" ],
|
||||
"http://www.w3.org/ns/sosa/hasFeatureOfInterest" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'Office_Humidity'"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/madeBySensor" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'DHT11'"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/observedProperty" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_Humidity'"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/dc/terms/created",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/dc/terms/creator",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/dc/terms/description",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/dc/terms/license",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/dc/terms/rights",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/dc/terms/title",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/vocab/vann/preferredNamespacePrefix",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://purl.org/vocab/vann/preferredNamespaceUri",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://schema.org/domainIncludes",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://schema.org/rangeIncludes",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/2004/02/skos/core#definition",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/2004/02/skos/core#example",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/2004/02/skos/core#note",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/2006/time#TemporalEntity",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Ontology" ],
|
||||
"http://purl.org/dc/terms/created" : [ {
|
||||
"@type" : "http://www.w3.org/2001/XMLSchema#date",
|
||||
"@value" : "2017-04-17"
|
||||
} ],
|
||||
"http://purl.org/dc/terms/creator" : [ {
|
||||
"@id" : "_:genid1"
|
||||
} ],
|
||||
"http://purl.org/dc/terms/description" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "This ontology is based on the SSN Ontology by the W3C Semantic Sensor Networks Incubator Group (SSN-XG), together with considerations from the W3C/OGC Spatial Data on the Web Working Group."
|
||||
} ],
|
||||
"http://purl.org/dc/terms/license" : [ {
|
||||
"@id" : "http://www.opengeospatial.org/ogc/Software"
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document"
|
||||
} ],
|
||||
"http://purl.org/dc/terms/rights" : [ {
|
||||
"@value" : "Copyright 2017 W3C/OGC."
|
||||
} ],
|
||||
"http://purl.org/dc/terms/title" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Sensor, Observation, Sample, and Actuator (SOSA) Ontology"
|
||||
} ],
|
||||
"http://purl.org/vocab/vann/preferredNamespacePrefix" : [ {
|
||||
"@value" : "sosa"
|
||||
} ],
|
||||
"http://purl.org/vocab/vann/preferredNamespaceUri" : [ {
|
||||
"@value" : "http://www.w3.org/ns/sosa/"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'Arduino_UNO_R3'",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Platform" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@value" : "Arduino Uno R3"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/Owner" : [ {
|
||||
"@value" : "04f5add581755fad29e698e053f2b923e5a15cc6bad9987bcb4dc79edb36cd54a732faae838841205461717391d0d198604d9d20a6a68b472339e1ff4874188d0a"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/hosts" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'DHT11'"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'DHT11'",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Sensor" ],
|
||||
"http://purl.org/dc/terms/creator" : [ {
|
||||
"@value" : "AOSONG"
|
||||
} ],
|
||||
"http://purl.org/dc/terms/description" : [ {
|
||||
"@value" : "Measures the temperature and humidity of the surrounding air.\nWorks on 3.3 - 5.5 volts"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@value" : "DHT11"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/Owner" : [ {
|
||||
"@value" : "04f5add581755fad29e698e053f2b923e5a15cc6bad9987bcb4dc79edb36cd54a732faae838841205461717391d0d198604d9d20a6a68b472339e1ff4874188d0a"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/observes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_Humidity'"
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_temperature'"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'Office_Humidity'",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/FeatureOfInterest" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@value" : "Office_Humidity"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'Office_temperature'",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/FeatureOfInterest" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@value" : "Office_temperature"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_Humidity'",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/ObservableProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@value" : "air_Humidity"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_temperature'",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/ObservableProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@value" : "air_temperature"
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/FeatureOfInterest",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The thing whose property is being estimated or calculated in the course of an Observation to arrive at a Result or whose property is being manipulated by an Actuator, or which is being sampled or transformed in an act of Sampling."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Feature Of Interest"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The thing whose property is being estimated or calculated in the course of an Observation to arrive at a Result or whose property is being manipulated by an Actuator, or which is being sampled or transformed in an act of Sampling."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "When measuring the height of a tree, the height is the observed ObservableProperty, 20m may be the Result of the Observation, and the tree is the FeatureOfInterest. A window is a FeatureOfInterest for an automatic window control Actuator."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/ObservableProperty",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "An observable quality (property, characteristic) of a FeatureOfInterest."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Observable Property"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "An observable quality (property, characteristic) of a FeatureOfInterest."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The height of a tree, the depth of a water body, or the temperature of a surface are examples of observable properties, while the value of a classic car is not (directly) observable but asserted."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Act of carrying out an (Observation) Procedure to estimate or calculate a value of a property of a FeatureOfInterest. Links to a Sensor to describe what made the Observation and how; links to an ObservableProperty to describe what the result is an estimate of, and to a FeatureOfInterest to detail what that property was associated with."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Act of carrying out an (Observation) Procedure to estimate or calculate a value of a property of a FeatureOfInterest. Links to a Sensor to describe what made the Observation and how; links to an ObservableProperty to describe what the result is an estimate of, and to a FeatureOfInterest to detail what that property was associated with."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The activity of estimating the intensity of an Earthquake using the Mercalli intensity scale is an Observation as is measuring the moment magnitude, i.e., the energy released by said earthquake."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Owner",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Platform",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A Platform is an entity that hosts other entities, particularly Sensors, Actuators, Samplers, and other Platforms."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Platform"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A Platform is an entity that hosts other entities, particularly Sensors, Actuators, Samplers, and other Platforms."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A post, buoy, vehicle, ship, aircraft, satellite, cell-phone, human or animal may act as platforms for (technical or biological) sensors or actuators."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/QuantityValue",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Result",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The Result of an Observation, Actuation, or act of Sampling. To store an observation's simple result value one can use the hasSimpleResult property."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Result"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The Result of an Observation, Actuation, or act of Sampling. To store an observation's simple result value one can use the hasSimpleResult property."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The value 20 as the height of a certain tree together with the unit, e.g., Meter."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Device, agent (including humans), or software (simulation) involved in, or implementing, a Procedure. Sensors respond to a stimulus, e.g., a change in the environment, or input data composed from the results of prior Observations, and generate a Result. Sensors can be hosted by Platforms."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Sensor"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#subClassOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Device, agent (including humans), or software (simulation) involved in, or implementing, a Procedure. Sensors respond to a stimulus, e.g., a change in the environment, or input data composed from the results of prior Observations, and generate a Result. Sensors can be hosted by Platforms."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Accelerometers, gyroscopes, barometers, magnetometers, and so forth are Sensors that are typically mounted on a modern smart phone (which acts as Platform). Other examples of sensors include the human eyes."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/actsOnProperty",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an Actuation and the property of a FeatureOfInterest it is acting upon."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "acts on property"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isActedOnBy"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an Actuation and the property of a FeatureOfInterest it is acting upon."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "In the activity (Actuation) of automatically closing a window if the temperature in a room drops below 20 degrees Celsius, the property on which the Actuator acts upon is the state of the window as it changes from being open to being closed. "
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/hasFeatureOfInterest",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/FeatureOfInterest"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A relation between an Observation and the entity whose quality was observed, or between an Actuation and the entity whose property was modified, or between an act of Sampling and the entity that was sampled."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "has feature of interest"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isFeatureOfInterestOf"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A relation between an Observation and the entity whose quality was observed, or between an Actuation and the entity whose property was modified, or between an act of Sampling and the entity that was sampled."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "For example, in an Observation of the weight of a person, the FeatureOfInterest is the person and the property is its weight."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/hasResult",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Result"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an Observation or Actuation or act of Sampling and a Result or Sample."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "has result"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isResultOf"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an Observation or Actuation or act of Sampling and a Result or Sample."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/hasSample",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/FeatureOfInterest"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a FeatureOfInterest and the Sample used to represent it."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "has sample"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isSampleOf"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a FeatureOfInterest and the Sample used to represent it."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/hasSimpleResult",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#DatatypeProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The simple value of an Observation or Actuation or act of Sampling."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "has simple result"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The simple value of an Observation or Actuation or act of Sampling."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "For instance, the values 23 or true."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/hosts",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Platform"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Platform"
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Platform and a Sensor, Actuator, Sampler, or Platform, hosted or mounted on it."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "hosts"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isHostedBy"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Platform and a Sensor, Actuator, Sampler, or Platform, hosted or mounted on it."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isActedOnBy",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an ActuatableProperty of a FeatureOfInterest and an Actuation changing its state."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "is acted on by"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an ActuatableProperty of a FeatureOfInterest and an Actuation changing its state."
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#example" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "In the activity (Actuation) of automatically closing a window if the temperature in a room drops below 20 degrees Celsius, the property on which the Actuator acts upon is the state of the window as it changes from being open to being closed. "
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isFeatureOfInterestOf",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/FeatureOfInterest"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A relation between a FeatureOfInterest and an Observation about it, an Actuation acting on it, or an act of Sampling that sampled it."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "is feature of interest of"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A relation between a FeatureOfInterest and an Observation about it, an Actuation acting on it, or an act of Sampling that sampled it."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isHostedBy",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Platform"
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Platform"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sensor, Actuator, Sampler, or Platform, and the Platform that it is mounted on or hosted by."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "is hosted by"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sensor, Actuator, Sampler, or Platform, and the Platform that it is mounted on or hosted by."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isObservedBy",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/ObservableProperty"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an ObservableProperty and the Sensor able to observe it."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "is observed by"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/observes"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an ObservableProperty and the Sensor able to observe it."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isResultOf",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Result"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking a Result to the Observation or Actuation or act of Sampling that created or caused it."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "is result of"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking a Result to the Observation or Actuation or act of Sampling that created or caused it."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/isSampleOf",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/FeatureOfInterest"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation from a Sample to the FeatureOfInterest that it is intended to be representative of."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "is sample of"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation from a Sample to the FeatureOfInterest that it is intended to be representative of."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeActuation",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an Actuator and the Actuation it has made."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "made actuation"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeByActuator"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an Actuator and the Actuation it has made."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeByActuator",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an Actuation to the Actuator that made that Actuation."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "made by actuator"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an Actuation to the Actuator that made that Actuation."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeBySampler",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an act of Sampling to the Sampler (sampling device or entity) that made it."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "made by sampler"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeSampling"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an act of Sampling to the Sampler (sampling device or entity) that made it."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeBySensor",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an Observation and the Sensor which made the Observation."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "made by sensor"
|
||||
} ],
|
||||
"http://www.w3.org/2002/07/owl#inverseOf" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeObservation"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between an Observation and the Sensor which made the Observation."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeObservation",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sensor and an Observation made by the Sensor."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "made observation"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sensor and an Observation made by the Sensor."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/madeSampling",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sampler (sampling device or entity) and the Sampling act it performed."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "made sampling"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sampler (sampling device or entity) and the Sampling act it performed."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/observedProperty",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/ObservableProperty"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an Observation to the property that was observed. The ObservableProperty should be a property of the FeatureOfInterest (linked by hasFeatureOfInterest) of this Observation."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "observed property"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation linking an Observation to the property that was observed. The ObservableProperty should be a property of the FeatureOfInterest (linked by hasFeatureOfInterest) of this Observation."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/observes",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Sensor"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/ObservableProperty"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sensor and an ObservableProperty that it is capable of sensing."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "observes"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "Relation between a Sensor and an ObservableProperty that it is capable of sensing."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/phenomenonTime",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://schema.org/rangeIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/2006/time#TemporalEntity"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The time that the Result of an Observation, Actuation or Sampling applies to the FeatureOfInterest. Not necessarily the same as the resultTime. May be an Interval or an Instant, or some other compound TemporalEntity."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "phenomenon time"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The time that the Result of an Observation, Actuation or Sampling applies to the FeatureOfInterest. Not necessarily the same as the resultTime. May be an Interval or an Instant, or some other compound TemporalEntity."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/resultTime",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#DatatypeProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The result time is the instant of time when the Observation, Actuation or Sampling activity was completed."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "result time"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#range" : [ {
|
||||
"@id" : "http://www.w3.org/2001/XMLSchema#dateTime"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "The result time is the instant of time when the Observation, Actuation or Sampling activity was completed."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://www.w3.org/ns/sosa/usedProcedure",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#ObjectProperty" ],
|
||||
"http://schema.org/domainIncludes" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/Observation"
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#comment" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A relation to link to a re-usable Procedure used in making an Observation, an Actuation, or a Sample, typically through a Sensor, Actuator or Sampler."
|
||||
} ],
|
||||
"http://www.w3.org/2000/01/rdf-schema#label" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "used procedure"
|
||||
} ],
|
||||
"http://www.w3.org/2004/02/skos/core#definition" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "A relation to link to a re-usable Procedure used in making an Observation, an Actuation, or a Sample, typically through a Sensor, Actuator or Sampler."
|
||||
} ]
|
||||
}, {
|
||||
"@id" : "http://xmlns.com/foaf/0.1/Agent",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#Class" ]
|
||||
}, {
|
||||
"@id" : "http://xmlns.com/foaf/0.1/name",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#AnnotationProperty" ]
|
||||
} ]
|
8
uploads/MetaTest.json
Normal file
8
uploads/MetaTest.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
[ {
|
||||
"@id" : "_:genid1",
|
||||
"@type" : [ "http://xmlns.com/foaf/0.1/Agent" ],
|
||||
"http://xmlns.com/foaf/0.1/name" : [ {
|
||||
"@language" : "en",
|
||||
"@value" : "W3C/OGC Spatial Data on the Web Working Group"
|
||||
} ]
|
||||
} ]
|
13
uploads/short2 DHT11 and arduino example.json
Normal file
13
uploads/short2 DHT11 and arduino example.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
[ {
|
||||
"@id" : "http://example.org/data/Observation/346344",
|
||||
"@type" : [ "http://www.w3.org/2002/07/owl#NamedIndividual", "http://www.w3.org/ns/sosa/Observation" ],
|
||||
"http://www.w3.org/ns/sosa/hasFeatureOfInterest" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'Office_temperature'"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/madeBySensor" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'DHT11'"
|
||||
} ],
|
||||
"http://www.w3.org/ns/sosa/observedProperty" : [ {
|
||||
"@id" : "http://www.w3.org/ns/sosa/'air_temperature'"
|
||||
} ]
|
||||
}]
|
BIN
wallet/.DS_Store
vendored
BIN
wallet/.DS_Store
vendored
Binary file not shown.
|
@ -1,67 +0,0 @@
|
|||
const ChainUtil = require('../chain-util');
|
||||
const { MINING_REWARD } = require('../config');
|
||||
|
||||
class CoinTransaction {
|
||||
constructor() {
|
||||
this.id = ChainUtil.id();
|
||||
this.input = null;
|
||||
this.outputs = [];
|
||||
}
|
||||
|
||||
update(senderWallet, recipient, amount) {
|
||||
const senderOutput = this.outputs.find(output => output.address === senderWallet.publicKey);
|
||||
if (amount > senderOutput.amount) {
|
||||
console.log(`Amount: ${amount} exceeds balance.`);
|
||||
return;
|
||||
}
|
||||
|
||||
senderOutput.amount = senderOutput.amount - amount;
|
||||
this.outputs.push({ amount, address: recipient });
|
||||
CoinTransaction.signCoinTransaction(this, senderWallet);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
static CoinTransactionWithOutputs(senderWallet, outputs) {
|
||||
const cointransaction = new this();
|
||||
cointransaction.outputs.push(...outputs);
|
||||
CoinTransaction.signCoinTransaction(cointransaction, senderWallet);
|
||||
return cointransaction;
|
||||
}
|
||||
|
||||
static newCoinTransaction(senderWallet, recipient, amount) {
|
||||
if (amount > senderWallet.balance) {
|
||||
console.log(`Amount: ${amount} exceeds balance.`);
|
||||
return;
|
||||
}
|
||||
|
||||
return CoinTransaction.CoinTransactionWithOutputs(senderWallet, [
|
||||
{ amount: senderWallet.balance - amount, address: senderWallet.publicKey},
|
||||
{ amount, address: recipient }]);
|
||||
}
|
||||
|
||||
static rewardCoinTransaction(minerWallet, blockchainWallet) {
|
||||
return CoinTransaction.CoinTransactionWithOutputs(blockchainWallet, [{
|
||||
amount: MINING_REWARD, address: minerWallet.publicKey
|
||||
}]);
|
||||
}
|
||||
|
||||
static signCoinTransaction(cointransaction, senderWallet) {
|
||||
cointransaction.input = {
|
||||
timestamp: Date.now(),
|
||||
amount: senderWallet.balance,
|
||||
address: senderWallet.publicKey,
|
||||
signature: senderWallet.sign(ChainUtil.hash(cointransaction.outputs))
|
||||
}
|
||||
}
|
||||
|
||||
static verifyCoinTransaction(cointransaction) {
|
||||
return ChainUtil.verifySignature(
|
||||
cointransaction.input.address,
|
||||
cointransaction.input.signature,
|
||||
ChainUtil.hash(cointransaction.outputs)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CoinTransaction;
|
|
@ -1,100 +0,0 @@
|
|||
const ChainUtil = require('../chain-util');
|
||||
|
||||
class MetaDataTransaction {
|
||||
constructor() {
|
||||
this.id = null; // if there is a problem in the metadata transaction, change null with ChainUtil.id();
|
||||
this.Signiture = null;
|
||||
this.Name = null;
|
||||
this.Geo = [];
|
||||
this.IP_URL = null;
|
||||
this.Topic_Token = null;
|
||||
this.Permission = null;
|
||||
this.RequestDetail = null;
|
||||
this.OrgOwner = null;
|
||||
this.DepOwner = null;
|
||||
this.PrsnOwner = null;
|
||||
this.MetaHash = null;
|
||||
this.PaymentPerKbyte = null;
|
||||
this.PaymentPerMinute = null;
|
||||
this.Protocol = null;
|
||||
this.MessageAttributes= {};
|
||||
this.Interval = null;
|
||||
this.FurtherDetails = null;
|
||||
this.SSNmetadata = null;
|
||||
|
||||
// this.Geo = null;
|
||||
// this.Std = null;
|
||||
// this.name= null;
|
||||
// this.MetaHash= null;
|
||||
// this.file=null;
|
||||
}
|
||||
|
||||
// update(senderWallet, Geo, URI, Name,Permission, OrgOwner, SSNmetadata) {
|
||||
|
||||
// this.Geo = Geo;
|
||||
// this.URI = URI;
|
||||
// this.Name = Name;
|
||||
// this.Permission = Permission;
|
||||
// this.OrgOwner = OrgOwner;
|
||||
// this.PrsnOwner = senderWallet.publicKey;
|
||||
// this.MetaHash = ChainUtil.hash(SSNmetadata);
|
||||
// this.SSNmetadata = SSNmetadata;
|
||||
|
||||
// MetaDatatransaction.signMetaDataTransaction(this, senderWallet);
|
||||
|
||||
// return this;
|
||||
// }
|
||||
|
||||
static MetaDataTransactionWithIoT(senderWallet, Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes, Intrval, FurtherDetails, SSNmetadata) {
|
||||
const metaDataTransaction = new this();
|
||||
metaDataTransaction.id = ChainUtil.id();
|
||||
metaDataTransaction.Name = Name;
|
||||
metaDataTransaction.Geo = Geo;
|
||||
metaDataTransaction.IP_URL = IP_URL;
|
||||
metaDataTransaction.Topic_Token = Topic_Token;
|
||||
metaDataTransaction.Permission = Permission;
|
||||
metaDataTransaction.RequestDetail = RequestDetail
|
||||
metaDataTransaction.OrgOwner = OrgOwner;
|
||||
metaDataTransaction.DepOwner = DepOwner;
|
||||
metaDataTransaction.PrsnOwner = PrsnOwner;
|
||||
metaDataTransaction.PaymentPerKbyte = PaymentPerKbyte ;
|
||||
metaDataTransaction.PaymentPerMinute = PaymentPerMinute;
|
||||
metaDataTransaction.Protocol = Protocol;
|
||||
metaDataTransaction.MessageAttributes = MessageAttributes;
|
||||
metaDataTransaction.MessageAttributes['DeviceID'] = metaDataTransaction.id;
|
||||
metaDataTransaction.MessageAttributes['DeviceName'] = Name;
|
||||
metaDataTransaction.MessageAttributes['Sensors'] =[{"SensorName":"","Value":"" , "Unit":""}];
|
||||
metaDataTransaction.MessageAttributes['TimeStamp'] = "";
|
||||
metaDataTransaction.Interval = Intrval;
|
||||
metaDataTransaction.FurtherDetails = FurtherDetails;
|
||||
metaDataTransaction.SSNmetadata = SSNmetadata;
|
||||
metaDataTransaction.MetaHash = ChainUtil.hash(SSNmetadata);
|
||||
MetaDataTransaction.signMetaDataTransaction(metaDataTransaction, senderWallet);
|
||||
return metaDataTransaction;
|
||||
}
|
||||
|
||||
|
||||
static newMetaDataTransaction(senderWallet,Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes, Interval, FurtherDetails, SSNmetadata){
|
||||
return MetaDataTransaction.MetaDataTransactionWithIoT(senderWallet, Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes, Interval, FurtherDetails, SSNmetadata
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
static signMetaDataTransaction (metaDataTransaction, senderWallet) {
|
||||
metaDataTransaction.Signiture = {
|
||||
timestamp: Date.now(),
|
||||
address: senderWallet.publicKey,
|
||||
signature: senderWallet.sign(ChainUtil.hash(metaDataTransaction.SSNmetadata))
|
||||
}
|
||||
}
|
||||
|
||||
static verifyMetaDataTransaction(metaDataTransaction) {
|
||||
return ChainUtil.verifySignature(
|
||||
metaDataTransaction.Signiture.address,
|
||||
metaDataTransaction.Signiture.signature,
|
||||
ChainUtil.hash(metaDataTransaction.SSNmetadata)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
module.exports = MetaDataTransaction;
|
|
@ -1,8 +1,7 @@
|
|||
const ChainUtil = require('../chain-util');
|
||||
const CoinTransaction = require('./CoinTransaction');
|
||||
const Transaction = require('./transaction');
|
||||
const { INITIAL_BALANCE } = require('../config');
|
||||
const MetaDataTransaction = require('./MetaDataTransaction');
|
||||
const transactionPool = require('./transaction-pool');
|
||||
const Metadata = require('./metadata');
|
||||
|
||||
class Wallet {
|
||||
constructor() {
|
||||
|
@ -21,49 +20,57 @@ class Wallet {
|
|||
return this.keyPair.sign(dataHash);
|
||||
}
|
||||
|
||||
createCoinTransaction(recipient, amount, blockchain, transactionPool) {
|
||||
// this.balance = this.calculateBalance(blockchain);
|
||||
createTransaction(recipient, amount, blockchain, transactionPool) {
|
||||
this.balance = this.calculateBalance(blockchain);
|
||||
|
||||
if (amount > this.balance) {
|
||||
console.log(`Amount: ${amount} exceceds current balance: ${this.balance}`);
|
||||
return;
|
||||
}
|
||||
if (amount > this.balance) {
|
||||
console.log(`Amount: ${amount} exceceds current balance: ${this.balance}`);
|
||||
return;
|
||||
}
|
||||
|
||||
let cointransaction = transactionPool.existingPaymentTransaction(this.publicKey);
|
||||
let transaction = transactionPool.existingTransaction(this.publicKey);
|
||||
|
||||
if (transaction) {
|
||||
transaction.update(this, recipient, amount);
|
||||
} else {
|
||||
transaction = Transaction.newTransaction(this, recipient, amount);
|
||||
transactionPool.updateOrAddTransaction(transaction);
|
||||
}
|
||||
|
||||
if (cointransaction) {
|
||||
cointransaction.update(this, recipient, amount);
|
||||
} else { //this should be the original one
|
||||
//just for test i make the transaction not to update if the sender is the same
|
||||
cointransaction = CoinTransaction.newCoinTransaction(this, recipient, amount);
|
||||
transactionPool.updateOrAddPaymentTransaction(cointransaction);
|
||||
}
|
||||
|
||||
return cointransaction;
|
||||
return transaction;
|
||||
}
|
||||
createMetaDataTransaction(Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes, Interval, FurtherDetails, SSNmetadata, transactionPool){
|
||||
/* let metaData = metaDataPool.existingMetaData(this.publicKey);
|
||||
|
||||
if (metaData) {
|
||||
metaData.update(this, Geo, Std, Name,MetaHash,file);
|
||||
} else {*/
|
||||
|
||||
const metaDataTransaction= MetaDataTransaction.newMetaDataTransaction(this, Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes,Interval, FurtherDetails, SSNmetadata);
|
||||
transactionPool.updateOrAddMetaDataTransaction(metaDataTransaction);
|
||||
//}
|
||||
return metaDataTransaction;
|
||||
}
|
||||
|
||||
createMetadata(Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,
|
||||
PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes, Interval,
|
||||
FurtherDetails, SSNmetadata, transactionPool){
|
||||
//let metadata = transactionPool.existingMetadata(this.publicKey);
|
||||
|
||||
// if (metaData) {
|
||||
// metadata.update(this, Geo, Std, Name,MetaHash,file);
|
||||
// } else {*/
|
||||
|
||||
let metadata= Metadata.newMetadata(this, Name,Geo ,IP_URL , Topic_Token, Permission,
|
||||
RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute,
|
||||
Protocol, MessageAttributes,Interval, FurtherDetails, SSNmetadata);
|
||||
transactionPool.AddMetadata(metadata);
|
||||
|
||||
//}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
|
||||
calculateBalance(blockchain) {
|
||||
let balance = this.balance;
|
||||
let cointransactions = [];
|
||||
blockchain.chain.forEach(block => block.data.forEach(cointransaction => {
|
||||
cointransactions.push(cointransaction);
|
||||
let transactions = [];
|
||||
blockchain.chain.forEach(block => block.data.forEach(transaction => {
|
||||
transactions.push(transaction);
|
||||
}));
|
||||
|
||||
const walletInputTs = cointransactions
|
||||
.filter(cointransaction => cointransaction.input.address === this.publicKey);
|
||||
console.log("transactions of balance")
|
||||
console.log(transactions);
|
||||
const PaymentTransactions = transactions[0];
|
||||
console.log("Payment transactions ")
|
||||
console.log(PaymentTransactions);
|
||||
const walletInputTs = PaymentTransactions.filter(transaction => transaction.input.address === this.publicKey);
|
||||
|
||||
let startTime = 0;
|
||||
|
||||
|
@ -76,9 +83,9 @@ class Wallet {
|
|||
startTime = recentInputT.input.timestamp;
|
||||
}
|
||||
|
||||
cointransactions.forEach(cointransaction => {
|
||||
if (cointransaction.input.timestamp > startTime) {
|
||||
cointransaction.outputs.find(output => {
|
||||
PaymentTransactions.forEach(transaction => {
|
||||
if (transaction.input.timestamp > startTime) {
|
||||
transaction.outputs.find(output => {
|
||||
if (output.address === this.publicKey) {
|
||||
balance += output.amount;
|
||||
}
|
||||
|
@ -96,4 +103,5 @@ class Wallet {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = Wallet;
|
||||
module.exports = Wallet;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('Wallet', () => {
|
|||
let wallet, tp, bc;
|
||||
|
||||
beforeEach(() => {
|
||||
wallet = new Wallet();
|
||||
wallet = new Wallet();
|
||||
tp = new TransactionPool();
|
||||
bc = new Blockchain();
|
||||
});
|
||||
|
@ -18,16 +18,12 @@ describe('Wallet', () => {
|
|||
beforeEach(() => {
|
||||
sendAmount = 50;
|
||||
recipient = 'r4nd0m-4ddr355';
|
||||
Geo = 20;
|
||||
Std = 9014;
|
||||
Name = 'temp';
|
||||
MetaHash = '123abcd';
|
||||
transaction = wallet.createCoinTransaction(recipient, sendAmount,Geo, Std, Name,MetaHash, bc, tp);
|
||||
transaction = wallet.createTransaction(recipient, sendAmount, bc, tp);
|
||||
});
|
||||
|
||||
describe('and doing the same transaction', () => {
|
||||
beforeEach(() => {
|
||||
wallet.createCoinTransaction(recipient, sendAmount,Geo, Std, Name,MetaHash, bc, tp);
|
||||
wallet.createTransaction(recipient, sendAmount, bc, tp);
|
||||
});
|
||||
|
||||
it('doubles the `sendAmount` subtracted from the wallet balance', () => {
|
||||
|
@ -50,9 +46,9 @@ describe('Wallet', () => {
|
|||
addBalance = 100;
|
||||
repeatAdd = 3;
|
||||
for (let i=0; i<repeatAdd; i++) {
|
||||
senderWallet.createCoinTransaction(wallet.publicKey, addBalance,Geo, Std, Name,MetaHash, bc, tp);
|
||||
senderWallet.createTransaction(wallet.publicKey, addBalance, bc, tp);
|
||||
}
|
||||
bc.addBlock(tp.paymenttransactions);
|
||||
bc.addBlock(tp.transactions);
|
||||
});
|
||||
|
||||
it('calculates the balance for blockchain transactions matching the recipient', () => {
|
||||
|
@ -70,15 +66,15 @@ describe('Wallet', () => {
|
|||
tp.clear();
|
||||
subtractBalance = 60;
|
||||
recipientBalance = wallet.calculateBalance(bc);
|
||||
wallet.createCoinTransaction(senderWallet.publicKey, subtractBalance,20,9014,'temp','123abc', bc, tp);
|
||||
bc.addBlock(tp.paymenttransactions);
|
||||
wallet.createTransaction(senderWallet.publicKey, subtractBalance, bc, tp);
|
||||
bc.addBlock(tp.transactions);
|
||||
});
|
||||
|
||||
describe('and the sender sends another transaction to the recipient', () => {
|
||||
beforeEach(() => {
|
||||
tp.clear();
|
||||
senderWallet.createCoinTransaction(wallet.publicKey, addBalance, 20,9014,'temp','123abc',bc, tp);
|
||||
bc.addBlock(tp.paymenttransactions);
|
||||
senderWallet.createTransaction(wallet.publicKey, addBalance, bc, tp);
|
||||
bc.addBlock(tp.transactions);
|
||||
});
|
||||
|
||||
it('calculate the recipient balance only using transactions since its most recent one', () => {
|
||||
|
|
88
wallet/metadata.js
Normal file
88
wallet/metadata.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
const ChainUtil = require('../chain-util');
|
||||
|
||||
class Metadata {
|
||||
constructor() {
|
||||
this.id = null;
|
||||
this.Signiture = null;
|
||||
this.Name = null;
|
||||
this.Geo = null;
|
||||
// this.GeospatialLocation = [];
|
||||
// this.Owenership = null;
|
||||
// this.Cost = null;
|
||||
// this.Identifications = null;
|
||||
// this.Integration = null;
|
||||
|
||||
this.IP_URL = null;
|
||||
this.Topic_Token = null;
|
||||
this.Permission = null;
|
||||
this.RequestDetail = null;
|
||||
this.OrgOwner = null;
|
||||
this.DepOwner = null;
|
||||
this.PrsnOwner = null;
|
||||
this.MetaHash = null;
|
||||
this.PaymentPerKbyte = null;
|
||||
this.PaymentPerMinute = null;
|
||||
this.Protocol = null;
|
||||
this.MessageAttributes= {};
|
||||
this.Interval = null;
|
||||
this.FurtherDetails = null;
|
||||
this.SSNmetadata = null;
|
||||
}
|
||||
|
||||
static MetadataOfIoTDevice(senderWallet, Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes, Intrval, FurtherDetails, SSNmetadata) {
|
||||
const metadata = new this();
|
||||
metadata.id = ChainUtil.id();
|
||||
metadata.Name = Name;
|
||||
metadata.Geo = Geo;
|
||||
metadata.IP_URL = IP_URL;
|
||||
metadata.Topic_Token = Topic_Token;
|
||||
metadata.Permission = Permission;
|
||||
metadata.RequestDetail = RequestDetail
|
||||
metadata.OrgOwner = OrgOwner;
|
||||
metadata.DepOwner = DepOwner;
|
||||
metadata.PrsnOwner = PrsnOwner;
|
||||
metadata.PaymentPerKbyte = PaymentPerKbyte ;
|
||||
metadata.PaymentPerMinute = PaymentPerMinute;
|
||||
metadata.Protocol = Protocol;
|
||||
metadata.MessageAttributes = MessageAttributes;
|
||||
// metadata.MessageAttributes['DeviceID'] = metadata.id;
|
||||
// metadata.MessageAttributes['DeviceName'] = Name;
|
||||
// metadata.MessageAttributes['Sensors'] =[{"SensorName":"","Value":"" , "Unit":""}];
|
||||
// metadata.MessageAttributes['TimeStamp'] = "";
|
||||
metadata.Interval = Intrval;
|
||||
metadata.FurtherDetails = FurtherDetails;
|
||||
metadata.SSNmetadata = SSNmetadata;
|
||||
metadata.MetaHash = ChainUtil.hash(SSNmetadata);
|
||||
Metadata.signMetadata(metadata, senderWallet);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
static newMetadata(senderWallet,Name,Geo ,IP_URL , Topic_Token, Permission, RequestDetail,
|
||||
OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol, MessageAttributes,
|
||||
Interval, FurtherDetails, SSNmetadata){
|
||||
return Metadata.MetadataOfIoTDevice(senderWallet, Name,Geo ,IP_URL , Topic_Token, Permission,
|
||||
RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte, PaymentPerMinute, Protocol,
|
||||
MessageAttributes, Interval, FurtherDetails, SSNmetadata
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
static signMetadata (metadata, senderWallet) {
|
||||
metadata.Signiture = {
|
||||
timestamp: Date.now(),
|
||||
address: senderWallet.publicKey,
|
||||
signature: senderWallet.sign(ChainUtil.hash(metadata.SSNmetadata))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static verifyMetadata(metadata) {
|
||||
return ChainUtil.verifySignature(
|
||||
metadata.Signiture.address,
|
||||
metadata.Signiture.signature,
|
||||
ChainUtil.hash(metadata.SSNmetadata)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Metadata;
|
109
wallet/metadata.test.js
Normal file
109
wallet/metadata.test.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
const Transaction = require('./transaction');
|
||||
const Metadata = require('./metadata');
|
||||
const Wallet = require('./index');
|
||||
const { MINING_REWARD } = require('../config');
|
||||
|
||||
describe('Transaction & Metadata', () => {
|
||||
let transaction, metadata, wallet, recipient, amount,
|
||||
senderWallet,Name,Geo ,IP_URL , Topic_Token, Permission,
|
||||
RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte,
|
||||
PaymentPerMinute, Protocol, MessageAttributes, Interval,
|
||||
FurtherDetails, SSNmetadata;
|
||||
|
||||
beforeEach(() => {
|
||||
wallet = new Wallet();
|
||||
amount = 50;
|
||||
recipient = 'r3c1p13nt';
|
||||
senderWallet = new Wallet();
|
||||
Name = 'IoT_Lab_Temp_Sensor'
|
||||
Geo = [1.045,0.0135]
|
||||
IP_URL = 'www.IoT-locationbar.com/sensors/temp'
|
||||
Topic_Token = 'ACCESS_TOKEN'
|
||||
Permission = 'Public'
|
||||
RequestDetail = 'Null'
|
||||
OrgOwner = 'Swinburne_University'
|
||||
DepOwner = 'Computer_Science'
|
||||
PrsnOwner = 'Anas_Dawod'
|
||||
PaymentPerKbyte = 10
|
||||
PaymentPerMinute = 5
|
||||
Protocol = 'MQTT'
|
||||
MessageAttributes = 'null'
|
||||
Interval = 10
|
||||
FurtherDetails = 'null'
|
||||
SSNmetadata = 'null'
|
||||
transaction = Transaction.newTransaction(wallet, recipient, amount);
|
||||
metadata = Metadata.newMetadata(senderWallet,Name,Geo ,IP_URL , Topic_Token, Permission,
|
||||
RequestDetail, OrgOwner, DepOwner,PrsnOwner, PaymentPerKbyte,
|
||||
PaymentPerMinute, Protocol, MessageAttributes, Interval,
|
||||
FurtherDetails, SSNmetadata)
|
||||
});
|
||||
|
||||
it('outputs the `amount` subtracted from the wallet balance', () => {
|
||||
expect(transaction.outputs.find(output => output.address === wallet.publicKey).amount)
|
||||
.toEqual(wallet.balance - amount);
|
||||
});
|
||||
|
||||
it('outputs the `amount` added to the recipient', () => {
|
||||
expect(transaction.outputs.find(output => output.address === recipient).amount)
|
||||
.toEqual(amount);
|
||||
});
|
||||
|
||||
it('inputs the balance of the wallet', () => {
|
||||
expect(transaction.input.amount).toEqual(wallet.balance);
|
||||
});
|
||||
|
||||
it('validates a valid transaction', () => {
|
||||
expect(Transaction.verifyTransaction(transaction)).toBe(true);
|
||||
});
|
||||
|
||||
it('validates a valid metadata', () => {
|
||||
expect(Metadata.verifyMetadata(metadata)).toBe(true);
|
||||
});
|
||||
|
||||
it('invalidates a corrupt transaction', () => {
|
||||
transaction.outputs[0].amount = 50000;
|
||||
expect(Transaction.verifyTransaction(transaction)).toBe(false);
|
||||
});
|
||||
|
||||
describe('transacting with an amount that exceeds the balance', () => {
|
||||
beforeEach(() => {
|
||||
amount = 50000;
|
||||
transaction = Transaction.newTransaction(wallet, recipient, amount);
|
||||
});
|
||||
|
||||
it('does not create the transaction', () => {
|
||||
expect(transaction).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('and updating a transaction', () => {
|
||||
let nextAmount, nextRecipient;
|
||||
|
||||
beforeEach(() => {
|
||||
nextAmount = 20;
|
||||
nextRecipient = 'n3xt-4ddr355';
|
||||
transaction = transaction.update(wallet, nextRecipient, nextAmount);
|
||||
});
|
||||
|
||||
it(`subtracts the next amount from the sender's output`, () => {
|
||||
expect(transaction.outputs.find(output => output.address === wallet.publicKey).amount)
|
||||
.toEqual(wallet.balance - amount - nextAmount);
|
||||
});
|
||||
|
||||
it('outputs an amount for the next recipient', () => {
|
||||
expect(transaction.outputs.find(output => output.address === nextRecipient).amount)
|
||||
.toEqual(nextAmount);
|
||||
});
|
||||
});
|
||||
|
||||
describe('creating a reward transaction', () => {
|
||||
beforeEach(() => {
|
||||
transaction = Transaction.rewardTransaction(wallet, Wallet.blockchainWallet());
|
||||
});
|
||||
|
||||
it(`reward the miner's wallet`, () => {
|
||||
expect(transaction.outputs.find(output => output.address === wallet.publicKey).amount)
|
||||
.toEqual(MINING_REWARD);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,118 +1,73 @@
|
|||
const PaymntTransaction = require('./CoinTransaction');
|
||||
const MetaDataTransaction = require('./MetaDataTransaction');
|
||||
//const CompTransaction = require('./CompTransaction');
|
||||
//const IntegrationTransaction = require('./IntegrationTransaction');
|
||||
const { MaxNumOfPaymentTransactions, MaxNumOfMetadataTransactions,
|
||||
MaxNumOfCompTransactions, MaxNumOfIntegrationTransactions}
|
||||
= require('../config');
|
||||
const Transaction = require('../wallet/transaction');
|
||||
const Metadata = require('../wallet/metadata')
|
||||
class TransactionPool {
|
||||
constructor() {
|
||||
this.paymenttransactions = [];
|
||||
this.metaDataTransactions =[];
|
||||
this.comptransactions = [];
|
||||
this.integrationTransactions =[];
|
||||
this.transactions = [];
|
||||
this.metadataS =[];
|
||||
}
|
||||
updateOrAddPaymentTransaction(paymenttransaction) {
|
||||
let paymenttransactionWithId = this.paymenttransactions.find(t =>
|
||||
t.id === paymenttransaction.id);
|
||||
if (paymenttransactionWithId) {
|
||||
this.paymenttransactions[this.paymenttransactions.indexOf
|
||||
(paymenttransactionWithId)] = paymenttransaction;
|
||||
} else {
|
||||
this.paymenttransactions.push(paymenttransaction);
|
||||
}
|
||||
}
|
||||
updateOrAddMetaDataTransaction(metaDataTransaction) {
|
||||
let metaDataTransactionWithId = this.metaDataTransactions.find(t =>
|
||||
t.id === metaDataTransaction.id);
|
||||
if (metaDataTransactionWithId) {
|
||||
this.metaDataTransactions[this.metaDataTransactions.indexOf
|
||||
(metaDataTransactionWithId)] = metaDataTransaction;
|
||||
|
||||
updateOrAddTransaction(transaction) {
|
||||
let transactionWithId = this.transactions.find(t => t.id === transaction.id);
|
||||
|
||||
if (transactionWithId) {
|
||||
this.transactions[this.transactions.indexOf(transactionWithId)] = transaction;
|
||||
} else {
|
||||
this.metaDataTransactions.push(metaDataTransaction);
|
||||
this.transactions.push(transaction);
|
||||
}
|
||||
}
|
||||
updateOrAddCompTransaction(comptransaction) {
|
||||
let comptransactionWithId = this.comptransactions.find(t =>
|
||||
t.id === comptransaction.id);
|
||||
if (comptransactionWithId) {
|
||||
this.comptransactions[this.comptransactions.indexOf
|
||||
(comptransactionWithId)] = comptransaction;
|
||||
} else {
|
||||
this.comptransactions.push(comptransaction);
|
||||
} }
|
||||
updateOrAddIntegrationTransaction(integrationTransaction) {
|
||||
let integrationTransactionWithId = this.integrationTransaction.find(
|
||||
t => t.id === integrationTransaction.id);
|
||||
if (integrationTransactionWithId) {
|
||||
this.integrationTransactions[this.integrationTransactions.indexOf
|
||||
(integrationTransactionWithId)] = integrationTransaction;
|
||||
} else {
|
||||
this.integrationTransactions.push(integrationTransaction);
|
||||
}
|
||||
|
||||
AddMetadata(metadata) {
|
||||
// let metadataWithId = this.metadataS.find(t => t.id === metadata.id);
|
||||
|
||||
// if (metadataWithId) {
|
||||
// this.metaDataS[this.metadataS.indexOf(metadataWithId)] = metadata;
|
||||
// } else {
|
||||
this.metadataS.push(metadata);
|
||||
// }
|
||||
}
|
||||
existingPaymentTransaction(address) {
|
||||
return this.paymenttransactions.find(t =>
|
||||
t.input.address === address); }
|
||||
existingMetaDataTransaction(address) {
|
||||
return this.metaDataTransactions.find(t =>
|
||||
t.Signiture.address === address);}
|
||||
existingCompTransaction(address) {
|
||||
return this.comptransactions.find(t =>
|
||||
t.input.address === address); }
|
||||
existingIntegrationTransaction(address) {
|
||||
return this.integrationTransactions.find(t =>
|
||||
t.Signiture.address === address);}
|
||||
validPaymentTransactions() {
|
||||
return this.paymenttransactions.filter(paymenttransaction => {
|
||||
const outputTotal = paymenttransaction.outputs.reduce(
|
||||
(total, output) => {
|
||||
|
||||
existingTransaction(address) {
|
||||
return this.transactions.find(t => t.input.address === address);
|
||||
}
|
||||
|
||||
existingMetadata(address) {
|
||||
return this.metadataS.find(t => t.Signiture.address === address);
|
||||
}
|
||||
|
||||
validTransactions() {
|
||||
return this.transactions.filter(transaction => {
|
||||
const outputTotal = transaction.outputs.reduce((total, output) => {
|
||||
return total + output.amount;
|
||||
}, 0);
|
||||
if (paymenttransaction.input.amount !== outputTotal) {
|
||||
console.log(`Invalid transaction from
|
||||
${paymenttransaction.input.address}.`);
|
||||
return;}
|
||||
if (!PaymentTransaction.verifyPaymentTransaction(
|
||||
paymenttransaction)) {
|
||||
console.log(`Invalid signature from
|
||||
${paymenttransaction.input.address}.`);
|
||||
return;}
|
||||
return paymenttransaction;
|
||||
|
||||
if (transaction.input.amount !== outputTotal) {
|
||||
console.log(`Invalid transaction from ${transaction.input.address}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Transaction.verifyTransaction(transaction)) {
|
||||
console.log(`Invalid signature from ${transaction.input.address}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
return transaction;
|
||||
});
|
||||
}
|
||||
validMetaDataTransactions(){
|
||||
if (!MetaDataTransaction.verifyMetaDataTransaction(
|
||||
metaDataTransaction)) {
|
||||
console.log(`Invalid signature from
|
||||
${metaDataTransaction.Signiture.address}.`);
|
||||
return;
|
||||
}
|
||||
return metaDataTransaction;
|
||||
|
||||
validMetadataS(){
|
||||
return this.metadataS.filter(metadata => {
|
||||
if (!Metadata.verifyMetadata(metadata)) {
|
||||
console.log(`Invalid signature from ${metadata.Signiture.address}.`);
|
||||
return;
|
||||
}
|
||||
return metadata;
|
||||
});
|
||||
}
|
||||
validCompTransactions(){
|
||||
if (!CompTransaction.verifyCompTransaction(
|
||||
CompTransaction)) {
|
||||
console.log(`Invalid signature from
|
||||
${CompTransaction.Signiture.address}.`);
|
||||
return;
|
||||
}
|
||||
return compTransaction;
|
||||
}
|
||||
validIntegrationTransactions(){
|
||||
if (!IntegrationTransaction.verifyIntegrationTransaction(
|
||||
integrationTransaction)) {
|
||||
console.log(`Invalid signature from
|
||||
${integrationTransaction.Signiture.address}.`);
|
||||
return;
|
||||
}
|
||||
return integrationTransaction;
|
||||
}
|
||||
clearAll() {
|
||||
this.cointransactions = [];
|
||||
this.metaDataTransactions = [];
|
||||
this.comptransactions = [];
|
||||
this.integrationTransactions = [];
|
||||
|
||||
clear() {
|
||||
this.transactions = [];
|
||||
this.metadataS = [];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TransactionPool;
|
|
@ -1,44 +1,72 @@
|
|||
const TransactionPool = require('./transaction-pool');
|
||||
const Transaction = require('./Cointransaction');
|
||||
const Transaction = require('./transaction');
|
||||
const Metadata = require('./metadata')
|
||||
const Wallet = require('./index');
|
||||
const Blockchain = require('../blockchain');
|
||||
|
||||
describe('TransactionPool', () => {
|
||||
let tp, wallet, transaction, bc;
|
||||
let tp, wallet, transaction, metadata, bc;
|
||||
|
||||
beforeEach(() => {
|
||||
tp = new TransactionPool();
|
||||
wallet = new Wallet();
|
||||
wallet2 =new Wallet();
|
||||
bc = new Blockchain();
|
||||
transaction = wallet.createCoinTransaction('r4nd-4dr355', 30,20,9014,'temp','123abc', bc, tp);
|
||||
transaction = wallet.createTransaction('r4nd-4dr355', 30, bc, tp);
|
||||
// senderWallet = 'address';
|
||||
// Name = 'IoT_Lab_Temp_Sensor'
|
||||
// Geo = [1.045,0.0135]
|
||||
// IP_URL = 'www.IoT-locationbar.com/sensors/temp'
|
||||
// Topic_Token = 'ACCESS_TOKEN'
|
||||
// Permission = 'Public'
|
||||
// RequestDetail = 'Null'
|
||||
// OrgOwner = 'Swinburne_University'
|
||||
// DepOwner = 'Computer_Science'
|
||||
// PrsnOwner = 'Anas_Dawod'
|
||||
// PaymentPerKbyte = 10
|
||||
// PaymentPerMinute = 5
|
||||
// Protocol = 'MQTT'
|
||||
// MessageAttributes = 'null'
|
||||
// Interval = 10
|
||||
// FurtherDetails = 'null'
|
||||
// SSNmetadata = 'null'
|
||||
|
||||
metadata = wallet.createMetadata('IoT_Lab_Temp_Sensor',[1.045,0.0135],"www.IoT-locationbar.com/sensors/temp" ,'ACCESS_TOKEN' , 'Public',
|
||||
'Null', 'Swinburne_University', 'Computer_Science','Anas_Dawod', 10,
|
||||
5, 'MQTT', 'null', 10,
|
||||
'FurtherDetails', 'SSNmetadata',tp);
|
||||
});
|
||||
|
||||
it('adds a transaction to the pool', () => {
|
||||
expect(tp.paymenttransactions.find(t => t.id === transaction.id)).toEqual(transaction);
|
||||
expect(tp.transactions.find(t => t.id === transaction.id)).toEqual(transaction);
|
||||
});
|
||||
it('adds a metadata to the pool', () => {
|
||||
expect(tp.metadataS.find(t => t.id === metadata.id)).toEqual(metadata);
|
||||
});
|
||||
|
||||
it('updates a transaction in the pool', () => {
|
||||
const oldTransaction = JSON.stringify(transaction);
|
||||
const newTransaction = transaction.update(wallet, 'foo-4ddr355', 40,20,9014,'temp','123abc');
|
||||
tp.updateOrAddPaymentTransaction(newTransaction);
|
||||
const newTransaction = transaction.update(wallet, 'foo-4ddr355', 40);
|
||||
tp.updateOrAddTransaction(newTransaction);
|
||||
|
||||
expect(JSON.stringify(tp.paymenttransactions.find(t => t.id === newTransaction.id)))
|
||||
expect(JSON.stringify(tp.transactions.find(t => t.id === newTransaction.id)))
|
||||
.not.toEqual(oldTransaction);
|
||||
});
|
||||
|
||||
it('clears transactions', () => {
|
||||
it('clears transactions and metadata', () => {
|
||||
tp.clear();
|
||||
expect(tp.paymenttransactions).toEqual([]);
|
||||
expect(tp.transactions).toEqual([]);
|
||||
expect(tp.metadataS).toEqual([]);
|
||||
});
|
||||
|
||||
describe('mixing valid and corrupt transactions', () => {
|
||||
let validTransactions;
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
validTransactions = [...tp.paymenttransactions];
|
||||
validTransactions = [...tp.transactions];
|
||||
for (let i=0; i<6; i++) {
|
||||
wallet = new Wallet();
|
||||
transaction = wallet.createCoinTransaction('r4nd-4dr355', 30,20,9014,'temp','123abc', bc, tp);
|
||||
transaction = wallet.createTransaction('r4nd-4dr355', 30, bc, tp);
|
||||
if (i%2==0) {
|
||||
transaction.input.amount = 99999;
|
||||
} else {
|
||||
|
@ -48,7 +76,7 @@ describe('TransactionPool', () => {
|
|||
});
|
||||
|
||||
it('shows a difference between valid and corrupt transactions', () => {
|
||||
expect(JSON.stringify(tp.paymenttransactions)).not.toEqual(JSON.stringify(validTransactions));
|
||||
expect(JSON.stringify(tp.transactions)).not.toEqual(JSON.stringify(validTransactions));
|
||||
});
|
||||
|
||||
it('grabs valid transactions', () => {
|
||||
|
|
69
wallet/transaction.js
Normal file
69
wallet/transaction.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
const ChainUtil = require('../chain-util');
|
||||
const { MINING_REWARD } = require('../config');
|
||||
|
||||
class Transaction {
|
||||
constructor() {
|
||||
this.id = ChainUtil.id();
|
||||
this.input = null;
|
||||
this.outputs = [];
|
||||
}
|
||||
|
||||
update(senderWallet, recipient, amount) {
|
||||
const senderOutput = this.outputs.find(output => output.address === senderWallet.publicKey);
|
||||
|
||||
if (amount > senderOutput.amount) {
|
||||
console.log(`Amount: ${amount} exceeds balance.`);
|
||||
return;
|
||||
}
|
||||
|
||||
senderOutput.amount = senderOutput.amount - amount;
|
||||
this.outputs.push({ amount, address: recipient });
|
||||
Transaction.signTransaction(this, senderWallet);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
static transactionWithOutputs(senderWallet, outputs) {
|
||||
const transaction = new this();
|
||||
transaction.outputs.push(...outputs);
|
||||
Transaction.signTransaction(transaction, senderWallet);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
static newTransaction(senderWallet, recipient, amount) {
|
||||
if (amount > senderWallet.balance) {
|
||||
console.log(`Amount: ${amount} exceeds balance.`);
|
||||
return;
|
||||
}
|
||||
|
||||
return Transaction.transactionWithOutputs(senderWallet, [
|
||||
{ amount: senderWallet.balance - amount, address: senderWallet.publicKey },
|
||||
{ amount, address: recipient }
|
||||
]);
|
||||
}
|
||||
|
||||
static rewardTransaction(minerWallet, blockchainWallet) {
|
||||
return Transaction.transactionWithOutputs(blockchainWallet, [{
|
||||
amount: MINING_REWARD, address: minerWallet.publicKey
|
||||
}]);
|
||||
}
|
||||
|
||||
static signTransaction(transaction, senderWallet) {
|
||||
transaction.input = {
|
||||
timestamp: Date.now(),
|
||||
amount: senderWallet.balance,
|
||||
address: senderWallet.publicKey,
|
||||
signature: senderWallet.sign(ChainUtil.hash(transaction.outputs))
|
||||
}
|
||||
}
|
||||
|
||||
static verifyTransaction(transaction) {
|
||||
return ChainUtil.verifySignature(
|
||||
transaction.input.address,
|
||||
transaction.input.signature,
|
||||
ChainUtil.hash(transaction.outputs)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Transaction;
|
|
@ -1,4 +1,4 @@
|
|||
const Transaction = require('./Cointransaction');
|
||||
const Transaction = require('./transaction');
|
||||
const Wallet = require('./index');
|
||||
const { MINING_REWARD } = require('../config');
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue