From 2aa7ea91a4026241df07582fc919b5267037b9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sat, 22 Jun 2019 20:11:28 +0300 Subject: [PATCH 01/10] Added initial frontend --- frontend/README.md | 6 + frontend/index.html | 90 +++++++++ frontend/index.js | 387 +++++++++++++++++++++++++++++++++++++ frontend/package.json | 31 +++ frontend/webpack.config.js | 35 ++++ 5 files changed, 549 insertions(+) create mode 100644 frontend/README.md create mode 100644 frontend/index.html create mode 100644 frontend/index.js create mode 100644 frontend/package.json create mode 100644 frontend/webpack.config.js diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..89d71e5 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,6 @@ +# Usage +1. run ```npm i``` + +2. run ```npm run build``` + +3. run ```npm run start``` \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..8153483 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,90 @@ + + + + + + Lazy snark dashboard + + + + + + +
+
+

+

+ Lazy snark dashboard +

+

+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ + + \ No newline at end of file diff --git a/frontend/index.js b/frontend/index.js new file mode 100644 index 0000000..a9d51a3 --- /dev/null +++ b/frontend/index.js @@ -0,0 +1,387 @@ +//CONNECT FLUENCE +$(document).ready(function() { + + // CONNECT WEB3 + if (typeof web3 !== 'undefined') { + // Use Mist/MetaMask's provider + let web3js = new Web3(web3.currentProvider); + } else { + console.log('No web3? You should consider trying MetaMask!'); + // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) + let web3js = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); + } + + //console.log(web3js); + + var controllerAddress = '0x2c13c996bad85b707ee7cf40b4e45d00abdf7d7b'; + let ControllerAbi = '[\n' + + '\t{\n' + + '\t\t"constant": false,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "id",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "challenge",\n' + + '\t\t"outputs": [],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "nonpayable",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": false,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "id",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "finzalize",\n' + + '\t\t"outputs": [],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "nonpayable",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": false,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "data",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "proof",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "submit",\n' + + '\t\t"outputs": [],\n' + + '\t\t"payable": true,\n' + + '\t\t"stateMutability": "payable",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"anonymous": false,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"indexed": true,\n' + + '\t\t\t\t"name": "sender",\n' + + '\t\t\t\t"type": "address"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"indexed": false,\n' + + '\t\t\t\t"name": "index",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"components": [\n' + + '\t\t\t\t\t\t\t{\n' + + '\t\t\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t\t}\n' + + '\t\t\t\t\t\t],\n' + + '\t\t\t\t\t\t"name": "data",\n' + + '\t\t\t\t\t\t"type": "tuple"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"components": [\n' + + '\t\t\t\t\t\t\t{\n' + + '\t\t\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t\t}\n' + + '\t\t\t\t\t\t],\n' + + '\t\t\t\t\t\t"name": "proof",\n' + + '\t\t\t\t\t\t"type": "tuple"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "submitter",\n' + + '\t\t\t\t\t\t"type": "address"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "timestamp",\n' + + '\t\t\t\t\t\t"type": "uint96"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "status",\n' + + '\t\t\t\t\t\t"type": "uint8"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"indexed": false,\n' + + '\t\t\t\t"name": "task",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "Submitted",\n' + + '\t\t"type": "event"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"anonymous": false,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"indexed": true,\n' + + '\t\t\t\t"name": "challenger",\n' + + '\t\t\t\t"type": "address"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"indexed": false,\n' + + '\t\t\t\t"name": "index",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "Challenged",\n' + + '\t\t"type": "event"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "id",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "getDataById",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"components": [\n' + + '\t\t\t\t\t\t\t{\n' + + '\t\t\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t\t}\n' + + '\t\t\t\t\t\t],\n' + + '\t\t\t\t\t\t"name": "data",\n' + + '\t\t\t\t\t\t"type": "tuple"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"components": [\n' + + '\t\t\t\t\t\t\t{\n' + + '\t\t\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t\t}\n' + + '\t\t\t\t\t\t],\n' + + '\t\t\t\t\t\t"name": "proof",\n' + + '\t\t\t\t\t\t"type": "tuple"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "submitter",\n' + + '\t\t\t\t\t\t"type": "address"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "timestamp",\n' + + '\t\t\t\t\t\t"type": "uint96"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "status",\n' + + '\t\t\t\t\t\t"type": "uint8"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "task",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "last5Timestamps",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "result",\n' + + '\t\t\t\t"type": "uint256[5]"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "stake",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "tasks",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "data",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "x",\n' + + '\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "proof",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "submitter",\n' + + '\t\t\t\t"type": "address"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "timestamp",\n' + + '\t\t\t\t"type": "uint96"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "status",\n' + + '\t\t\t\t"type": "uint8"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "verifier",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "address"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t}\n' + + ']'; + ControllerAbi = JSON.parse(ControllerAbi); + //console.log(ControllerAbi); + let ControllerContract = web3.eth.contract(ControllerAbi); + //console.log(ControllerContract); + let contractInstance = ControllerContract.at(controllerAddress); + //console.log(contractInstance); +/* + // save fluence to global variable, so it can be accessed from Developer Console + window.fluence = fluence; + + // convert result to a string + window.getResultAsString = function (result) { + return result.result().then((r) => r.asString()) + }; + + window.logResultAsString = function (result) { + return getResultAsString(result).then((r) => console.log(r)) + }; +*/ +console.log(contractInstance); +contractInstance.last5Timestamps(function (err, result) { + console.log(result); + for (let i = 0; i < 5; i++) { + $('#state-id-' + i).text(result[i]); + } +}); + + + /*window.onload = function () { + + // address to Fluence contract in Ethereum blockchain. Interaction with blockchain created by MetaMask or with local Ethereum node + let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01"; + + // set ethUrl to `undefined` to use MetaMask instead of Ethereum node + let ethUrl = "http://geth.fluence.one:8545/"; + + // application to interact with that stored in Fluence contract + let appId = "218"; + + // create a session between client and backend application, and then join the game + fluence.connect(contractAddress, appId, ethUrl).then((s) => { + console.log("Session created"); + window.session = s; + }).then(() => join()); + + + // send request to list last txses + + for (let i = 0; i < 5; i++) { + let id = document.getElementById('state-id-' + i).textContent; + contractInstance.giveDataFromId(id, function (err, result) { + + let fluenceResponse = session.request(`{ "player_id": ${id}, "action": "GetBalance"}`); + $('#state-status-fluence-' + i).text(fluenceResponse); + if (fluenceResponse == true) { + $('challenge-' + i).prop('disabled', true); + } else { + $('challenge-' + i).text('Challenge on Ethereum!') + } + }); + } + + };*/ + + + $('button').click(function () { + //console.log($(this)[0].id.slice(-1)); + if ($(this)[0].textContent === 'Challenge on Fluence!') { + let id = $(this)[0].id.slice(-1); + //console.log(id); + //console.log(contractInstance); + contractInstance.getDataById(id, function (err, result) { + //console.log(err); + console.log(result); + // let fluenceResponse = session.request(JSON.stringify(request)); + // $('#state-status-fluence-' + i).text(result); + // if (fluenceResponse === true) { + // $('challenge-' + i).prop('disabled', true); + // } else { + // $('#challenge-' + i).text('Challenge on Ethereum!') + // } + }); + // } else { + // challengeEthereum(id); + } + }); +}); + +function challengeEthereum(jobId) { + contractInstance.challenge.sendTransaction(jobId, function (err, txHash) { + $('challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); + }); +} + + +import * as fluence from "fluence"; diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..337fe53 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,31 @@ +{ + "name": "frontend-challenger", + "version": "1.0.0", + "description": "", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "webpack-dev-server", + "build": "webpack" + }, + "files": [ + "index.html" + ], + "keywords": [], + "author": "", + "devDependencies": { + "copy-webpack-plugin": "^5.0.2", + "css-loader": "^2.1.1", + "html-webpack-plugin": "^3.2.0", + "style-loader": "0.23.1", + "webpack": "^4.29.6", + "webpack-cli": "^3.3.0", + "webpack-dev-server": "^3.2.1", + "web3": "1.0.0-beta.55" + }, + "dependencies": { + "Package": "0.0.1", + "fluence": "0.1.26" + } +} + diff --git a/frontend/webpack.config.js b/frontend/webpack.config.js new file mode 100644 index 0000000..136e96c --- /dev/null +++ b/frontend/webpack.config.js @@ -0,0 +1,35 @@ +const path = require('path'); +const webpack = require('webpack'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + // use index.js as entrypoint + entry: { + app: ['./index.js'] + }, + devServer: { + contentBase: './bundle', + hot: true + }, + mode: "development", + module: { + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + } + ] + }, + // build all code in `bundle.js` in `bundle` directory + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'bundle') + }, + plugins: [ + // create `index.html` with imported `bundle.js` + new CopyWebpackPlugin([{ + from: './*.html' + }]), + new webpack.HotModuleReplacementPlugin() + ] +}; From 024eaab74c4316d980668996ac4674fbca219ee6 Mon Sep 17 00:00:00 2001 From: Evgeny Marchenko Date: Sat, 22 Jun 2019 20:33:01 +0300 Subject: [PATCH 02/10] yet another getter --- truffle/contracts/Lazy.sol | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/truffle/contracts/Lazy.sol b/truffle/contracts/Lazy.sol index 404b215..78310ed 100644 --- a/truffle/contracts/Lazy.sol +++ b/truffle/contracts/Lazy.sol @@ -19,6 +19,9 @@ contract Lazy is Structs { } Task[] public tasks; + function tasksNum() external view returns(uint) { + return tasks.length; + } uint256 public stake; IVerifier public verifier; @@ -65,6 +68,21 @@ contract Lazy is Structs { msg.sender.transfer(stake); } + function taskDataById(uint id) external view returns( + uint[5] memory input, + uint[2] memory a, + uint[4] memory b, + uint[2] memory c + ) { + Task memory task = tasks[id]; + input = task.data.input; + a = task.proof.a; + b[0] = task.proof.b[0][0]; + b[1] = task.proof.b[0][1]; + b[2] = task.proof.b[1][0]; + b[3] = task.proof.b[1][1]; + c = task.proof.c; + } function last5Timestamps() view external returns (uint256[5] memory result) { From 470fc06a9d3a87e7f0f3d4fd805e3a84cb80ef9e Mon Sep 17 00:00:00 2001 From: Evgeny Marchenko Date: Sat, 22 Jun 2019 21:28:57 +0300 Subject: [PATCH 03/10] simplify getter even more --- truffle/contracts/Lazy.sol | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/truffle/contracts/Lazy.sol b/truffle/contracts/Lazy.sol index 78310ed..87cf7af 100644 --- a/truffle/contracts/Lazy.sol +++ b/truffle/contracts/Lazy.sol @@ -69,19 +69,26 @@ contract Lazy is Structs { } function taskDataById(uint id) external view returns( - uint[5] memory input, - uint[2] memory a, - uint[4] memory b, - uint[2] memory c + uint[13] memory data ) { Task memory task = tasks[id]; - input = task.data.input; - a = task.proof.a; - b[0] = task.proof.b[0][0]; - b[1] = task.proof.b[0][1]; - b[2] = task.proof.b[1][0]; - b[3] = task.proof.b[1][1]; - c = task.proof.c; + + data[0] = task.data.input[0]; + data[1] = task.data.input[1]; + data[2] = task.data.input[2]; + data[3] = task.data.input[3]; + data[4] = task.data.input[4]; + + data[5] = task.proof.a[0]; + data[6] = task.proof.a[1]; + + data[7] = task.proof.b[0][0]; + data[8] = task.proof.b[0][1]; + data[9] = task.proof.b[1][0]; + data[10] = task.proof.b[1][0]; + + data[11] = task.proof.c[0]; + data[12] = task.proof.c[1]; } From ec8236bebc2a6af7a55da2247b167e49d12d0ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sat, 22 Jun 2019 22:10:05 +0300 Subject: [PATCH 04/10] Full Eth interaction --- frontend/index.js | 418 +++++++++++++++++++++++++--------------------- 1 file changed, 223 insertions(+), 195 deletions(-) diff --git a/frontend/index.js b/frontend/index.js index a9d51a3..b05f1c9 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -1,4 +1,6 @@ //CONNECT FLUENCE +var contractInstance; + $(document).ready(function() { // CONNECT WEB3 @@ -13,22 +15,8 @@ $(document).ready(function() { //console.log(web3js); - var controllerAddress = '0x2c13c996bad85b707ee7cf40b4e45d00abdf7d7b'; + var controllerAddress = '0x64748b0c0b28079cf88345c1dd992d543d9f028a'; let ControllerAbi = '[\n' + - '\t{\n' + - '\t\t"constant": false,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "id",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "challenge",\n' + - '\t\t"outputs": [],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "nonpayable",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + '\t{\n' + '\t\t"constant": false,\n' + '\t\t"inputs": [\n' + @@ -44,13 +32,55 @@ $(document).ready(function() { '\t\t"type": "function"\n' + '\t},\n' + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "last5Timestamps",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "result",\n' + + '\t\t\t\t"type": "uint256[5]"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "verifier",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "address"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "stake",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + '\t\t"constant": false,\n' + '\t\t"inputs": [\n' + '\t\t\t{\n' + '\t\t\t\t"components": [\n' + '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t"name": "input",\n' + + '\t\t\t\t\t\t"type": "uint256[5]"\n' + '\t\t\t\t\t}\n' + '\t\t\t\t],\n' + '\t\t\t\t"name": "data",\n' + @@ -59,8 +89,16 @@ $(document).ready(function() { '\t\t\t{\n' + '\t\t\t\t"components": [\n' + '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t"name": "a",\n' + + '\t\t\t\t\t\t"type": "uint256[2]"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "b",\n' + + '\t\t\t\t\t\t"type": "uint256[2][2]"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "c",\n' + + '\t\t\t\t\t\t"type": "uint256[2]"\n' + '\t\t\t\t\t}\n' + '\t\t\t\t],\n' + '\t\t\t\t"name": "proof",\n' + @@ -74,6 +112,108 @@ $(document).ready(function() { '\t\t"type": "function"\n' + '\t},\n' + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "tasks",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "input",\n' + + '\t\t\t\t\t\t"type": "uint256[5]"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "data",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"components": [\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "a",\n' + + '\t\t\t\t\t\t"type": "uint256[2]"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "b",\n' + + '\t\t\t\t\t\t"type": "uint256[2][2]"\n' + + '\t\t\t\t\t},\n' + + '\t\t\t\t\t{\n' + + '\t\t\t\t\t\t"name": "c",\n' + + '\t\t\t\t\t\t"type": "uint256[2]"\n' + + '\t\t\t\t\t}\n' + + '\t\t\t\t],\n' + + '\t\t\t\t"name": "proof",\n' + + '\t\t\t\t"type": "tuple"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "submitter",\n' + + '\t\t\t\t"type": "address"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "timestamp",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t},\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "status",\n' + + '\t\t\t\t"type": "uint8"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "id",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "taskDataById",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "data",\n' + + '\t\t\t\t"type": "uint256[13]"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": false,\n' + + '\t\t"inputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "id",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"name": "challenge",\n' + + '\t\t"outputs": [],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "nonpayable",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + + '\t\t"constant": true,\n' + + '\t\t"inputs": [],\n' + + '\t\t"name": "tasksNum",\n' + + '\t\t"outputs": [\n' + + '\t\t\t{\n' + + '\t\t\t\t"name": "",\n' + + '\t\t\t\t"type": "uint256"\n' + + '\t\t\t}\n' + + '\t\t],\n' + + '\t\t"payable": false,\n' + + '\t\t"stateMutability": "view",\n' + + '\t\t"type": "function"\n' + + '\t},\n' + + '\t{\n' + '\t\t"anonymous": false,\n' + '\t\t"inputs": [\n' + '\t\t\t{\n' + @@ -91,8 +231,8 @@ $(document).ready(function() { '\t\t\t\t\t{\n' + '\t\t\t\t\t\t"components": [\n' + '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t\t\t"name": "input",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256[5]"\n' + '\t\t\t\t\t\t\t}\n' + '\t\t\t\t\t\t],\n' + '\t\t\t\t\t\t"name": "data",\n' + @@ -101,8 +241,16 @@ $(document).ready(function() { '\t\t\t\t\t{\n' + '\t\t\t\t\t\t"components": [\n' + '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256"\n' + + '\t\t\t\t\t\t\t\t"name": "a",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256[2]"\n' + + '\t\t\t\t\t\t\t},\n' + + '\t\t\t\t\t\t\t{\n' + + '\t\t\t\t\t\t\t\t"name": "b",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256[2][2]"\n' + + '\t\t\t\t\t\t\t},\n' + + '\t\t\t\t\t\t\t{\n' + + '\t\t\t\t\t\t\t\t"name": "c",\n' + + '\t\t\t\t\t\t\t\t"type": "uint256[2]"\n' + '\t\t\t\t\t\t\t}\n' + '\t\t\t\t\t\t],\n' + '\t\t\t\t\t\t"name": "proof",\n' + @@ -114,7 +262,7 @@ $(document).ready(function() { '\t\t\t\t\t},\n' + '\t\t\t\t\t{\n' + '\t\t\t\t\t\t"name": "timestamp",\n' + - '\t\t\t\t\t\t"type": "uint96"\n' + + '\t\t\t\t\t\t"type": "uint256"\n' + '\t\t\t\t\t},\n' + '\t\t\t\t\t{\n' + '\t\t\t\t\t\t"name": "status",\n' + @@ -145,155 +293,13 @@ $(document).ready(function() { '\t\t],\n' + '\t\t"name": "Challenged",\n' + '\t\t"type": "event"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "id",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "getDataById",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"components": [\n' + - '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256"\n' + - '\t\t\t\t\t\t\t}\n' + - '\t\t\t\t\t\t],\n' + - '\t\t\t\t\t\t"name": "data",\n' + - '\t\t\t\t\t\t"type": "tuple"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"components": [\n' + - '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256"\n' + - '\t\t\t\t\t\t\t}\n' + - '\t\t\t\t\t\t],\n' + - '\t\t\t\t\t\t"name": "proof",\n' + - '\t\t\t\t\t\t"type": "tuple"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "submitter",\n' + - '\t\t\t\t\t\t"type": "address"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "timestamp",\n' + - '\t\t\t\t\t\t"type": "uint96"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "status",\n' + - '\t\t\t\t\t\t"type": "uint8"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "task",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "last5Timestamps",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "result",\n' + - '\t\t\t\t"type": "uint256[5]"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "stake",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "tasks",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t"type": "uint256"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "data",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "x",\n' + - '\t\t\t\t\t\t"type": "uint256"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "proof",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "submitter",\n' + - '\t\t\t\t"type": "address"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "timestamp",\n' + - '\t\t\t\t"type": "uint96"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "status",\n' + - '\t\t\t\t"type": "uint8"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "verifier",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "address"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + '\t}\n' + ']'; ControllerAbi = JSON.parse(ControllerAbi); //console.log(ControllerAbi); let ControllerContract = web3.eth.contract(ControllerAbi); //console.log(ControllerContract); - let contractInstance = ControllerContract.at(controllerAddress); + contractInstance = ControllerContract.at(controllerAddress); //console.log(contractInstance); /* // save fluence to global variable, so it can be accessed from Developer Console @@ -308,13 +314,28 @@ $(document).ready(function() { return getResultAsString(result).then((r) => console.log(r)) }; */ -console.log(contractInstance); -contractInstance.last5Timestamps(function (err, result) { - console.log(result); - for (let i = 0; i < 5; i++) { - $('#state-id-' + i).text(result[i]); - } -}); + + + contractInstance.tasksNum(function (err, result) { + console.log(result); + let maxLen = Math.min(result, 5); + for (let i = 0; i < maxLen; i++) { + let data = result - 1 - i; + let fluenceResponse = session.request(`{"action": "Check", "proof_id": ${data}}`); + + $('#state-id-' + i).text(result - 1 - i); + if (fluenceResponse.hasOwnProperty('verified')) { + if (fluenceResponse.verified) { + // все хорошо - мы проверили в флюенсе + $('challenge-' + i).prop('disabled', true); + } else { + // мы проверили, пруф неправильный + $('#challenge-' + i).text('Challenge on Ethereum!') + } + } + } + }); + /*window.onload = function () { @@ -354,29 +375,36 @@ contractInstance.last5Timestamps(function (err, result) { };*/ - $('button').click(function () { - //console.log($(this)[0].id.slice(-1)); - if ($(this)[0].textContent === 'Challenge on Fluence!') { - let id = $(this)[0].id.slice(-1); - //console.log(id); - //console.log(contractInstance); - contractInstance.getDataById(id, function (err, result) { - //console.log(err); - console.log(result); - // let fluenceResponse = session.request(JSON.stringify(request)); - // $('#state-status-fluence-' + i).text(result); - // if (fluenceResponse === true) { - // $('challenge-' + i).prop('disabled', true); - // } else { - // $('#challenge-' + i).text('Challenge on Ethereum!') - // } - }); - // } else { - // challengeEthereum(id); - } - }); + }); +$('button').click(function () { + //console.log($(this)[0].id.slice(-1)); + if ($(this)[0].textContent === 'Challenge on Fluence!') { + let id = $(this)[0].id.slice(-1); + let data = $('#state-id-' + id)[0].textContent; + console.log(data); + //console.log(contractInstance); + contractInstance.taskDataById(data, function (err, result) { + //console.log(err); + console.log(result); + let public_par = result.slice(0, 5); + let proof = result.slice(5, 13); + let fluenceResponse = session.request(`{"action": "Verify", "proof_id": ${data}, "public_par": ${public_par}, "proof": ${proof}}`); + console.log(fluenceResponse); + $('#state-status-fluence-' + i).text(result); + if (fluenceResponse.result) { + // все хорошо - мы проверили в флюенсе + $('challenge-' + i).prop('disabled', true); + } else { + // мы проверили, пруф неправильный + $('#challenge-' + i).text('Challenge on Ethereum!') + } + }); + } else { + challengeEthereum(data); + } +}); function challengeEthereum(jobId) { contractInstance.challenge.sendTransaction(jobId, function (err, txHash) { $('challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); From 65e29304086357c63c091cc1601be9064082caf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sat, 22 Jun 2019 22:14:54 +0300 Subject: [PATCH 05/10] Fixed button name --- frontend/index.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/index.js b/frontend/index.js index b05f1c9..20b652f 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -327,7 +327,7 @@ $(document).ready(function() { if (fluenceResponse.hasOwnProperty('verified')) { if (fluenceResponse.verified) { // все хорошо - мы проверили в флюенсе - $('challenge-' + i).prop('disabled', true); + $('#challenge-' + i).prop('disabled', true); } else { // мы проверили, пруф неправильный $('#challenge-' + i).text('Challenge on Ethereum!') @@ -374,8 +374,6 @@ $(document).ready(function() { };*/ - - }); $('button').click(function () { @@ -395,7 +393,7 @@ $('button').click(function () { $('#state-status-fluence-' + i).text(result); if (fluenceResponse.result) { // все хорошо - мы проверили в флюенсе - $('challenge-' + i).prop('disabled', true); + $('#challenge-' + i).prop('disabled', true); } else { // мы проверили, пруф неправильный $('#challenge-' + i).text('Challenge on Ethereum!') @@ -405,9 +403,10 @@ $('button').click(function () { challengeEthereum(data); } }); + function challengeEthereum(jobId) { contractInstance.challenge.sendTransaction(jobId, function (err, txHash) { - $('challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); + $('#challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); }); } From 9da7f55b50a034c656a336513705248ead501f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sat, 22 Jun 2019 22:45:16 +0300 Subject: [PATCH 06/10] Added fluence --- frontend/index.js | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/frontend/index.js b/frontend/index.js index 20b652f..996edc1 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -1,21 +1,30 @@ //CONNECT FLUENCE +import * as fluence from "fluence"; + +let session; +window.onload = function () { + let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01"; + + // set ethUrl to `undefined` to use MetaMask instead of Ethereum node + let ethUrl = "http://geth.fluence.one:8545/"; + + // application to interact with that stored in Fluence contract + let appId = "261"; + + // create a session between client and backend application, and then join the game + fluence.connect(contractAddress, appId, ethUrl).then((s) => { + console.log("Session created"); + session = s; + }); +}; + + var contractInstance; $(document).ready(function() { - // CONNECT WEB3 - if (typeof web3 !== 'undefined') { - // Use Mist/MetaMask's provider - let web3js = new Web3(web3.currentProvider); - } else { - console.log('No web3? You should consider trying MetaMask!'); - // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) - let web3js = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); - } - //console.log(web3js); - - var controllerAddress = '0x64748b0c0b28079cf88345c1dd992d543d9f028a'; + var controllerAddress = '0x1cca1f0be338c747b11a16aba8d0905251628bdf'; let ControllerAbi = '[\n' + '\t{\n' + '\t\t"constant": false,\n' + @@ -322,14 +331,16 @@ $(document).ready(function() { for (let i = 0; i < maxLen; i++) { let data = result - 1 - i; let fluenceResponse = session.request(`{"action": "Check", "proof_id": ${data}}`); - + console.log(fluenceResponse); $('#state-id-' + i).text(result - 1 - i); if (fluenceResponse.hasOwnProperty('verified')) { if (fluenceResponse.verified) { // все хорошо - мы проверили в флюенсе + $('#state-status-fluence-' + i).text('TRUE by Fluence.'); $('#challenge-' + i).prop('disabled', true); } else { // мы проверили, пруф неправильный + $('#state-status-fluence-' + i).text('FALSE by Fluence.'); $('#challenge-' + i).text('Challenge on Ethereum!') } } @@ -409,6 +420,3 @@ function challengeEthereum(jobId) { $('#challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); }); } - - -import * as fluence from "fluence"; From 1610284b41f5bb434ca4073fe7286d128f4d87e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sat, 22 Jun 2019 23:22:55 +0300 Subject: [PATCH 07/10] Refactored code --- frontend/index.js | 717 +++++++++++++++++++++++----------------------- 1 file changed, 366 insertions(+), 351 deletions(-) diff --git a/frontend/index.js b/frontend/index.js index 996edc1..5813429 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -6,10 +6,10 @@ window.onload = function () { let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01"; // set ethUrl to `undefined` to use MetaMask instead of Ethereum node - let ethUrl = "http://geth.fluence.one:8545/"; + let ethUrl = "http://rinkeby.fluence.one:8545/"; // application to interact with that stored in Fluence contract - let appId = "261"; + let appId = "264"; // create a session between client and backend application, and then join the game fluence.connect(contractAddress, appId, ethUrl).then((s) => { @@ -22,316 +22,369 @@ window.onload = function () { var contractInstance; $(document).ready(function() { + // window.addEventListener('load', () => { + // if (typeof Web3 !== 'undefined') { + // let web3js = new Web3(web3.currentProvider); + // } else { + // console.log('No web3? You should consider trying MetaMask!'); + // let web3js = new Web3(new Web3.providers.HttpProvider('http://localhost:8080')); + // } + // }); + // console.log('provider'); + // console.log(web3js); var controllerAddress = '0x1cca1f0be338c747b11a16aba8d0905251628bdf'; - let ControllerAbi = '[\n' + - '\t{\n' + - '\t\t"constant": false,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "id",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "finzalize",\n' + - '\t\t"outputs": [],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "nonpayable",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "last5Timestamps",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "result",\n' + - '\t\t\t\t"type": "uint256[5]"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "verifier",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "address"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "stake",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": false,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "input",\n' + - '\t\t\t\t\t\t"type": "uint256[5]"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "data",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "a",\n' + - '\t\t\t\t\t\t"type": "uint256[2]"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "b",\n' + - '\t\t\t\t\t\t"type": "uint256[2][2]"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "c",\n' + - '\t\t\t\t\t\t"type": "uint256[2]"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "proof",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "submit",\n' + - '\t\t"outputs": [],\n' + - '\t\t"payable": true,\n' + - '\t\t"stateMutability": "payable",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "tasks",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "input",\n' + - '\t\t\t\t\t\t"type": "uint256[5]"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "data",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "a",\n' + - '\t\t\t\t\t\t"type": "uint256[2]"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "b",\n' + - '\t\t\t\t\t\t"type": "uint256[2][2]"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "c",\n' + - '\t\t\t\t\t\t"type": "uint256[2]"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"name": "proof",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "submitter",\n' + - '\t\t\t\t"type": "address"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "timestamp",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "status",\n' + - '\t\t\t\t"type": "uint8"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "id",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "taskDataById",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "data",\n' + - '\t\t\t\t"type": "uint256[13]"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": false,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "id",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "challenge",\n' + - '\t\t"outputs": [],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "nonpayable",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"constant": true,\n' + - '\t\t"inputs": [],\n' + - '\t\t"name": "tasksNum",\n' + - '\t\t"outputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"name": "",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"payable": false,\n' + - '\t\t"stateMutability": "view",\n' + - '\t\t"type": "function"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"anonymous": false,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"indexed": true,\n' + - '\t\t\t\t"name": "sender",\n' + - '\t\t\t\t"type": "address"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"indexed": false,\n' + - '\t\t\t\t"name": "index",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"components": [\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"components": [\n' + - '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "input",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256[5]"\n' + - '\t\t\t\t\t\t\t}\n' + - '\t\t\t\t\t\t],\n' + - '\t\t\t\t\t\t"name": "data",\n' + - '\t\t\t\t\t\t"type": "tuple"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"components": [\n' + - '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "a",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256[2]"\n' + - '\t\t\t\t\t\t\t},\n' + - '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "b",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256[2][2]"\n' + - '\t\t\t\t\t\t\t},\n' + - '\t\t\t\t\t\t\t{\n' + - '\t\t\t\t\t\t\t\t"name": "c",\n' + - '\t\t\t\t\t\t\t\t"type": "uint256[2]"\n' + - '\t\t\t\t\t\t\t}\n' + - '\t\t\t\t\t\t],\n' + - '\t\t\t\t\t\t"name": "proof",\n' + - '\t\t\t\t\t\t"type": "tuple"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "submitter",\n' + - '\t\t\t\t\t\t"type": "address"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "timestamp",\n' + - '\t\t\t\t\t\t"type": "uint256"\n' + - '\t\t\t\t\t},\n' + - '\t\t\t\t\t{\n' + - '\t\t\t\t\t\t"name": "status",\n' + - '\t\t\t\t\t\t"type": "uint8"\n' + - '\t\t\t\t\t}\n' + - '\t\t\t\t],\n' + - '\t\t\t\t"indexed": false,\n' + - '\t\t\t\t"name": "task",\n' + - '\t\t\t\t"type": "tuple"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "Submitted",\n' + - '\t\t"type": "event"\n' + - '\t},\n' + - '\t{\n' + - '\t\t"anonymous": false,\n' + - '\t\t"inputs": [\n' + - '\t\t\t{\n' + - '\t\t\t\t"indexed": true,\n' + - '\t\t\t\t"name": "challenger",\n' + - '\t\t\t\t"type": "address"\n' + - '\t\t\t},\n' + - '\t\t\t{\n' + - '\t\t\t\t"indexed": false,\n' + - '\t\t\t\t"name": "index",\n' + - '\t\t\t\t"type": "uint256"\n' + - '\t\t\t}\n' + - '\t\t],\n' + - '\t\t"name": "Challenged",\n' + - '\t\t"type": "event"\n' + - '\t}\n' + - ']'; - ControllerAbi = JSON.parse(ControllerAbi); - //console.log(ControllerAbi); + let ControllerAbi = [ + { + "constant": true, + "inputs": [], + "name": "verifier", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "stake", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "tasks", + "outputs": [ + { + "components": [ + { + "name": "input", + "type": "uint256[5]" + } + ], + "name": "data", + "type": "tuple" + }, + { + "components": [ + { + "name": "a", + "type": "uint256[2]" + }, + { + "name": "b", + "type": "uint256[2][2]" + }, + { + "name": "c", + "type": "uint256[2]" + } + ], + "name": "proof", + "type": "tuple" + }, + { + "name": "submitter", + "type": "address" + }, + { + "name": "timestamp", + "type": "uint256" + }, + { + "name": "status", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "name": "index", + "type": "uint256" + }, + { + "components": [ + { + "components": [ + { + "name": "input", + "type": "uint256[5]" + } + ], + "name": "data", + "type": "tuple" + }, + { + "components": [ + { + "name": "a", + "type": "uint256[2]" + }, + { + "name": "b", + "type": "uint256[2][2]" + }, + { + "name": "c", + "type": "uint256[2]" + } + ], + "name": "proof", + "type": "tuple" + }, + { + "name": "submitter", + "type": "address" + }, + { + "name": "timestamp", + "type": "uint256" + }, + { + "name": "status", + "type": "uint8" + } + ], + "indexed": false, + "name": "task", + "type": "tuple" + } + ], + "name": "Submitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "challenger", + "type": "address" + }, + { + "indexed": false, + "name": "index", + "type": "uint256" + } + ], + "name": "Challenged", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "tasksNum", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "components": [ + { + "name": "input", + "type": "uint256[5]" + } + ], + "name": "data", + "type": "tuple" + }, + { + "components": [ + { + "name": "a", + "type": "uint256[2]" + }, + { + "name": "b", + "type": "uint256[2][2]" + }, + { + "name": "c", + "type": "uint256[2]" + } + ], + "name": "proof", + "type": "tuple" + } + ], + "name": "submit", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "name": "challenge", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "name": "finzalize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "name": "taskDataById", + "outputs": [ + { + "name": "data", + "type": "uint256[13]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "last5Timestamps", + "outputs": [ + { + "name": "result", + "type": "uint256[5]" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "id", + "type": "uint256" + } + ], + "name": "getDataById", + "outputs": [ + { + "components": [ + { + "components": [ + { + "name": "input", + "type": "uint256[5]" + } + ], + "name": "data", + "type": "tuple" + }, + { + "components": [ + { + "name": "a", + "type": "uint256[2]" + }, + { + "name": "b", + "type": "uint256[2][2]" + }, + { + "name": "c", + "type": "uint256[2]" + } + ], + "name": "proof", + "type": "tuple" + }, + { + "name": "submitter", + "type": "address" + }, + { + "name": "timestamp", + "type": "uint256" + }, + { + "name": "status", + "type": "uint8" + } + ], + "name": "task", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } + ]; let ControllerContract = web3.eth.contract(ControllerAbi); - //console.log(ControllerContract); contractInstance = ControllerContract.at(controllerAddress); - //console.log(contractInstance); -/* - // save fluence to global variable, so it can be accessed from Developer Console - window.fluence = fluence; - - // convert result to a string - window.getResultAsString = function (result) { - return result.result().then((r) => r.asString()) - }; - - window.logResultAsString = function (result) { - return getResultAsString(result).then((r) => console.log(r)) - }; -*/ - contractInstance.tasksNum(function (err, result) { console.log(result); let maxLen = Math.min(result, 5); for (let i = 0; i < maxLen; i++) { let data = result - 1 - i; - let fluenceResponse = session.request(`{"action": "Check", "proof_id": ${data}}`); - console.log(fluenceResponse); + // let fluenceResponse = session.request(`{"action": "Check", "proof_id": ${data}}`); + // console.log(fluenceResponse); $('#state-id-' + i).text(result - 1 - i); if (fluenceResponse.hasOwnProperty('verified')) { if (fluenceResponse.verified) { @@ -346,68 +399,29 @@ $(document).ready(function() { } } }); - - - - /*window.onload = function () { - - // address to Fluence contract in Ethereum blockchain. Interaction with blockchain created by MetaMask or with local Ethereum node - let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01"; - - // set ethUrl to `undefined` to use MetaMask instead of Ethereum node - let ethUrl = "http://geth.fluence.one:8545/"; - - // application to interact with that stored in Fluence contract - let appId = "218"; - - // create a session between client and backend application, and then join the game - fluence.connect(contractAddress, appId, ethUrl).then((s) => { - console.log("Session created"); - window.session = s; - }).then(() => join()); - - - // send request to list last txses - - for (let i = 0; i < 5; i++) { - let id = document.getElementById('state-id-' + i).textContent; - contractInstance.giveDataFromId(id, function (err, result) { - - let fluenceResponse = session.request(`{ "player_id": ${id}, "action": "GetBalance"}`); - $('#state-status-fluence-' + i).text(fluenceResponse); - if (fluenceResponse == true) { - $('challenge-' + i).prop('disabled', true); - } else { - $('challenge-' + i).text('Challenge on Ethereum!') - } - }); - } - - };*/ - }); $('button').click(function () { - //console.log($(this)[0].id.slice(-1)); + let id = $(this)[0].id.slice(-1); + let data = $('#state-id-' + id)[0].textContent; + if ($(this)[0].textContent === 'Challenge on Fluence!') { - let id = $(this)[0].id.slice(-1); - let data = $('#state-id-' + id)[0].textContent; - console.log(data); - //console.log(contractInstance); contractInstance.taskDataById(data, function (err, result) { - //console.log(err); - console.log(result); let public_par = result.slice(0, 5); let proof = result.slice(5, 13); + let fluenceResponse = session.request(`{"action": "Verify", "proof_id": ${data}, "public_par": ${public_par}, "proof": ${proof}}`); console.log(fluenceResponse); - $('#state-status-fluence-' + i).text(result); - if (fluenceResponse.result) { + // let success = fluenceResponse.result === 1; + let success = false; + if (success) { // все хорошо - мы проверили в флюенсе - $('#challenge-' + i).prop('disabled', true); + $('#state-status-fluence-' + id).text('TRUE by Fluence.'); + $('#challenge-' + id).prop('disabled', true); } else { // мы проверили, пруф неправильный - $('#challenge-' + i).text('Challenge on Ethereum!') + $('#state-status-fluence-' + id).text('FALSE by Fluence.'); + $('#challenge-' + id).text('Challenge on Ethereum!') } }); } else { @@ -416,6 +430,7 @@ $('button').click(function () { }); function challengeEthereum(jobId) { + console.log(jobId); contractInstance.challenge.sendTransaction(jobId, function (err, txHash) { $('#challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); }); From ff7e3ce92b5f881a910c60f0b9306cec2a53779e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sun, 23 Jun 2019 11:51:31 +0300 Subject: [PATCH 08/10] Version ready for deploy --- frontend/index.html | 7 ++- frontend/index.js | 91 ++++++++++++++++++++------------------ frontend/webpack.config.js | 2 +- 3 files changed, 54 insertions(+), 46 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 8153483..b6ed871 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6,7 +6,6 @@ Lazy snark dashboard - @@ -38,6 +37,7 @@
+

@@ -49,6 +49,7 @@
+

@@ -60,6 +61,8 @@
+

+
@@ -71,6 +74,7 @@
+

@@ -82,6 +86,7 @@
+

diff --git a/frontend/index.js b/frontend/index.js index 5813429..4354c51 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -1,7 +1,7 @@ //CONNECT FLUENCE import * as fluence from "fluence"; -let session; +//let session; window.onload = function () { let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01"; @@ -14,25 +14,17 @@ window.onload = function () { // create a session between client and backend application, and then join the game fluence.connect(contractAddress, appId, ethUrl).then((s) => { console.log("Session created"); - session = s; + window.session = s; }); }; +window.getResultAsString = function (result) { + return result.result().then((r) => r.asString()) +}; var contractInstance; $(document).ready(function() { - // window.addEventListener('load', () => { - // if (typeof Web3 !== 'undefined') { - // let web3js = new Web3(web3.currentProvider); - // } else { - // console.log('No web3? You should consider trying MetaMask!'); - // let web3js = new Web3(new Web3.providers.HttpProvider('http://localhost:8080')); - // } - // }); - - // console.log('provider'); - // console.log(web3js); var controllerAddress = '0x1cca1f0be338c747b11a16aba8d0905251628bdf'; let ControllerAbi = [ @@ -377,26 +369,31 @@ $(document).ready(function() { ]; let ControllerContract = web3.eth.contract(ControllerAbi); contractInstance = ControllerContract.at(controllerAddress); + window.ethereum.enable(); contractInstance.tasksNum(function (err, result) { - console.log(result); let maxLen = Math.min(result, 5); for (let i = 0; i < maxLen; i++) { let data = result - 1 - i; - // let fluenceResponse = session.request(`{"action": "Check", "proof_id": ${data}}`); - // console.log(fluenceResponse); - $('#state-id-' + i).text(result - 1 - i); - if (fluenceResponse.hasOwnProperty('verified')) { - if (fluenceResponse.verified) { - // все хорошо - мы проверили в флюенсе - $('#state-status-fluence-' + i).text('TRUE by Fluence.'); - $('#challenge-' + i).prop('disabled', true); + $('#state-id-' + i).text(data); + let fluenceResponse_check = session.request(`{"action": "Check", "proof_id": ${data}}`); + getResultAsString(fluenceResponse_check).then(function (str) { + let fluenceResponse = JSON.parse(str); + console.log(fluenceResponse); + if (fluenceResponse.hasOwnProperty('verifed')) { + if (fluenceResponse.verifed) { + // все хорошо - мы проверили в флюенсе + $('#state-status-fluence-' + i).text('TRUE by Fluence.'); + $('#challenge-' + i).prop('disabled', true); + } else { + // мы проверили, пруф неправильный + $('#state-status-fluence-' + i).text('FALSE by Fluence.'); + $('#challenge-' + i).text('Challenge on Ethereum!') + } } else { - // мы проверили, пруф неправильный - $('#state-status-fluence-' + i).text('FALSE by Fluence.'); - $('#challenge-' + i).text('Challenge on Ethereum!') + console.log('Task N ' + data + ' is not checked on Fluence!') } - } + }); } }); }); @@ -410,28 +407,34 @@ $('button').click(function () { let public_par = result.slice(0, 5); let proof = result.slice(5, 13); - let fluenceResponse = session.request(`{"action": "Verify", "proof_id": ${data}, "public_par": ${public_par}, "proof": ${proof}}`); - console.log(fluenceResponse); - // let success = fluenceResponse.result === 1; - let success = false; - if (success) { - // все хорошо - мы проверили в флюенсе - $('#state-status-fluence-' + id).text('TRUE by Fluence.'); - $('#challenge-' + id).prop('disabled', true); - } else { - // мы проверили, пруф неправильный - $('#state-status-fluence-' + id).text('FALSE by Fluence.'); - $('#challenge-' + id).text('Challenge on Ethereum!') - } + let fluenceResponse_ver = session.request(`{"action": "Verify", "proof_id": ${data}, "public_par": [${public_par}], "proof": [${proof}]}`); + getResultAsString(fluenceResponse_ver).then(function (str) { + let fluenceResponse = JSON.parse(str); + let success = fluenceResponse.result === 1; + console.log(fluenceResponse); + if (success) { + // все хорошо - мы проверили в флюенсе + $('#state-status-fluence-' + id).text('TRUE by Fluence.'); + $('#challenge-' + id).prop('disabled', true); + } else { + // мы проверили, пруф неправильный + $('#state-status-fluence-' + id).text('FALSE by Fluence.'); + $('#challenge-' + id).text('Challenge on Ethereum!') + } + }); }); + } else if ($(this)[0].textContent === 'Challenge on Ethereum!') { + challengeEthereum(id, data); } else { - challengeEthereum(data); + } }); -function challengeEthereum(jobId) { - console.log(jobId); - contractInstance.challenge.sendTransaction(jobId, function (err, txHash) { - $('#challenge-' + jobId).text('See tx on Etherscan!').attr("href", "https://ropsten.etherscan.io/tx/" + txHash); +function challengeEthereum(id, data) { + console.log('Challenging task N ' + data + ' on Ethereum!'); + contractInstance.challenge.sendTransaction(data, function (err, txHash) { + $('#challenge-' + id).remove(); + $('#link-' + id).text('See tx on Etherscan!').attr("href", "https://rinkeby.etherscan.io/tx/" + txHash); + }); } diff --git a/frontend/webpack.config.js b/frontend/webpack.config.js index 136e96c..e755938 100644 --- a/frontend/webpack.config.js +++ b/frontend/webpack.config.js @@ -11,7 +11,7 @@ module.exports = { contentBase: './bundle', hot: true }, - mode: "development", + mode: "production", module: { rules: [ { From 3907a1fdf19a8247a1b3a91784eefb717690441d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sun, 23 Jun 2019 12:01:09 +0300 Subject: [PATCH 09/10] Version ready for deploy --- frontend/README.md | 2 ++ frontend/index.js | 23 ++++++++++------------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/frontend/README.md b/frontend/README.md index 89d71e5..0dc4a9c 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,4 +1,6 @@ # Usage +0. set the `appId` (Fluence) and `lazyAddress` (Eth contract) in `index.js` + 1. run ```npm i``` 2. run ```npm run build``` diff --git a/frontend/index.js b/frontend/index.js index 4354c51..bab5bc2 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -1,8 +1,14 @@ //CONNECT FLUENCE import * as fluence from "fluence"; -//let session; -window.onload = function () { + +window.getResultAsString = function (result) { + return result.result().then((r) => r.asString()) +}; + +var contractInstance; + +$(document).ready(function() { let contractAddress = "0xeFF91455de6D4CF57C141bD8bF819E5f873c1A01"; // set ethUrl to `undefined` to use MetaMask instead of Ethereum node @@ -16,17 +22,8 @@ window.onload = function () { console.log("Session created"); window.session = s; }); -}; -window.getResultAsString = function (result) { - return result.result().then((r) => r.asString()) -}; - -var contractInstance; - -$(document).ready(function() { - - var controllerAddress = '0x1cca1f0be338c747b11a16aba8d0905251628bdf'; + var lazyAddress = '0x1cca1f0be338c747b11a16aba8d0905251628bdf'; let ControllerAbi = [ { "constant": true, @@ -368,7 +365,7 @@ $(document).ready(function() { } ]; let ControllerContract = web3.eth.contract(ControllerAbi); - contractInstance = ControllerContract.at(controllerAddress); + contractInstance = ControllerContract.at(lazyAddress); window.ethereum.enable(); contractInstance.tasksNum(function (err, result) { From 7dedd56ee6b3b9f488c86c7ac5e2ecc0ab99a3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=A1=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Sun, 23 Jun 2019 12:03:50 +0300 Subject: [PATCH 10/10] Fixed initial html --- frontend/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index b6ed871..22551f9 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -30,7 +30,7 @@
- +
@@ -42,7 +42,7 @@
- +
@@ -54,7 +54,7 @@
- +
@@ -67,7 +67,7 @@
- +
@@ -79,7 +79,7 @@
- +