Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

js-audit draft version #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,43 @@
# js-audit
# JS-AUDIT

A CLI tool for a verifying Public Traces from Gotrace.

## Installation

Clone the repository:

```
git clone [email protected]:chainparency/js-audit.git
```

Install the dependencies:

```
npm i
```


## Usage

1. To download a public trace:

```
node index.js download PUBLIC_TRACE_ID
```

2. To verify a downloaded trace:

```
node index.js verify PUBLIC_TRACE_ID
```

## Manual public trace verification

1. Download and verify a public trace using the download/verify commands using this cli
2. Install multihash library https://github.com/multiformats/go-multihash/tree/master/multihash
3. Calculate hash of every checkpoint using the following command:

```
multihash -algorithm="sha2-256" -encoding="base58" checkpoint_{CHECKPOINT_ID}
```
4. Confirm that calculated hash and the hash on the blockchain are the same (https://explorer.gochain.io/tx/TX_ID).
42 changes: 42 additions & 0 deletions commands/download.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const chalk = require('chalk')
var fs = require('fs');

async function download(id) {
console.log(chalk.yellow(`Downloading trace ${id}...`))
let url = `https://api.gotrace.world/v1/public/trace/${id}`
console.log(chalk.green.bold('The public trace ' + id + ' is being downloaded'))
try {
res = await fetch(url)
} catch (error) {
console.log(chalk.red.bold(`The public trace ${url} cannot be downloaded: ` + error))
}
let parsedData = await res.json()
fs.writeFileSync(`public_trace_${id}.json`, JSON.stringify(parsedData), function (err) {
if (err) throw err;
chalk.red.bold('The public trace cannot be saved: ' + err);
}
);
if (parsedData.trace != null && parsedData.trace.supply_graph != null && parsedData.trace.supply_graph.shipments[id] != null) {
filteredArray = parsedData.trace.supply_graph.shipments[id].events.filter(function (element) {
return element.multihash !== undefined;
});
console.log(chalk.green.bold('The public trace ' + id + ' have ' + filteredArray.length + ' events'))
for (const element of filteredArray) {
let url = `https://api.gotrace.world/v1/public/eventFile/${element.multihash}`
try {
response = await fetch(url)
} catch (error) {
console.log(chalk.red.bold(`The event file ${url} cannot be downloaded: ` + error))
}
let data = await response.text()
fs.writeFileSync(`checkpoint_${element.multihash}.json`, data, function (err) {
if (err) {
chalk.red.bold(`The public trace for ${element.multihash} cannot be saved: ` + err);
}
}
);
}
}
}

module.exports = download
51 changes: 51 additions & 0 deletions commands/verify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const chalk = require('chalk')
const fs = require('fs');
const crypto = require('crypto')
const bs58 = require('bs58')
const Web3 = require('web3');


const SHA256Prefix = '1220'
const inputs = [
{
"indexed": false,
"name": "multihash",
"type": "string"
}
]


async function verify(id) {
console.log(chalk.yellow(`Verifying a trace ${id}...`))
let path = `public_trace_${id}.json`
if (!fs.existsSync(path)) {
throw new Error('File is not found: ' + path + ' try to download it again')
}
let data = fs.readFileSync(path)
parsedData = JSON.parse(data);
if (parsedData.trace != null && parsedData.trace.supply_graph != null && parsedData.trace.supply_graph.shipments[id] != null) {
filteredArray = parsedData.trace.supply_graph.shipments[id].events.filter(function (element) {
return element.multihash !== undefined;
});
console.log(chalk.green.bold('The public trace ' + id + ' have ' + filteredArray.length + ' events'))
for (const element of filteredArray) {
const buff = fs.readFileSync(`checkpoint_${element.multihash}.json`);
multihash = SHA256Prefix + crypto.createHash('sha256').update(buff).digest('hex')
const bs58String = bs58.encode(Buffer.from(multihash, "hex"))
let web3 = new Web3("https://rpc.gochain.io");
receipt = await web3.eth.getTransactionReceipt(element.tx_hash);
let result = web3.eth.abi.decodeLog(inputs, receipt.logs[0].data, receipt.logs[0].topics)
if (result.multihash == bs58String) {
console.log(chalk.green(`The public trace checkpoint ${element.multihash} is verified, hashes are the same, calculated hash: ${bs58String}, hash from the blockchain: ${result.multihash}, tx_id: ${element.tx_hash}`))
} else {
console.log(chalk.red.bold('The public trace checkpoint ' + element.multihash + ' is not verified, hashes are different'))
}
}
} else {
console.log(chalk.red.bold('The trace ' + id + ' is not verified'))
throw new Error('Trace data is wrong, try to download it again')
}

}

module.exports = verify
40 changes: 40 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#! /usr/bin/env node
const { program } = require('commander')
const verify = require('./commands/verify')
const download = require('./commands/download')
const chalk = require('chalk')


program
.command('verify <task>')
.description('Verify a dowloaded public trace')
.action(function (task) {
return verify(task)
.then(function () {
console.log(chalk.green.bold('Successfully verified a public trace'))
process.exit(0)
})
.catch(function (error) {
console.log(chalk.red.bold('Verification failed:', error))
})
})

program
.command('download <id>')
.description('Download a public trace')
.action(function (id) {
return download(id)
.then(function () {
console.log(
chalk.green.bold('The public trace ' + id + ' have been downloaded')
)
process.exit(0)
})
.catch(function (error) {
console.log(
chalk.red.bold('Failed to download ' + id + ' error: ' + error)
)
})
})

program.parse()
Loading