mirror of
https://github.com/fluencelabs/lazy-snark
synced 2025-04-27 07:52:14 +00:00
commit
4bf2dbffbe
8
frontend/README.md
Normal file
8
frontend/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Usage
|
||||||
|
0. set the `appId` (Fluence) and `lazyAddress` (Eth contract) in `index.js`
|
||||||
|
|
||||||
|
1. run ```npm i```
|
||||||
|
|
||||||
|
2. run ```npm run build```
|
||||||
|
|
||||||
|
3. run ```npm run start```
|
95
frontend/index.html
Normal file
95
frontend/index.html
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Required meta tags -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Lazy snark dashboard</title>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<p> </p>
|
||||||
|
<h3>
|
||||||
|
Lazy snark dashboard
|
||||||
|
</h3>
|
||||||
|
<p> </p>
|
||||||
|
</div>
|
||||||
|
<div class="row 0">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<label id="state-id">State ID's</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label id="state-status-fluence">Fluence status</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<label id="challenge">Challenge?</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row 1">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<label id="state-id-0">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label id="state-status-fluence-0">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<button type="button" class="btn btn-primary" id="challenge-0">Challenge on Fluence!</button>
|
||||||
|
<p><a id = "link-0" target="_blank"></a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row 2">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<label id="state-id-1">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label id="state-status-fluence-1">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<button type="button" class="btn btn-primary" id="challenge-1">Challenge on Fluence!</button>
|
||||||
|
<p><a id = "link-1" target="_blank"></a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row 3">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<label id="state-id-2">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label id="state-status-fluence-2">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<button type="button" class="btn btn-primary" id="challenge-2">Challenge on Fluence!</button>
|
||||||
|
<p><a id = "link-2" target="_blank"></a></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row 4">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<label id="state-id-3">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label id="state-status-fluence-3">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<button type="button" class="btn btn-primary" id="challenge-3">Challenge on Fluence!</button>
|
||||||
|
<p><a id = "link-3" target="_blank"></a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row 5">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<label id="state-id-4">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<label id="state-status-fluence-4">None</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<button type="button" class="btn btn-primary" id="challenge-4">Challenge on Fluence!</button>
|
||||||
|
<p><a id = "link-4" target="_blank"></a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script src="bundle.js"></script>
|
||||||
|
</html>
|
437
frontend/index.js
Normal file
437
frontend/index.js
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
//CONNECT FLUENCE
|
||||||
|
import * as fluence from "fluence";
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
let ethUrl = "http://rinkeby.fluence.one:8545/";
|
||||||
|
|
||||||
|
// application to interact with that stored in Fluence contract
|
||||||
|
let appId = "264";
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
});
|
||||||
|
|
||||||
|
var lazyAddress = '0x1cca1f0be338c747b11a16aba8d0905251628bdf';
|
||||||
|
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);
|
||||||
|
contractInstance = ControllerContract.at(lazyAddress);
|
||||||
|
window.ethereum.enable();
|
||||||
|
|
||||||
|
contractInstance.tasksNum(function (err, result) {
|
||||||
|
let maxLen = Math.min(result, 5);
|
||||||
|
for (let i = 0; i < maxLen; i++) {
|
||||||
|
let data = result - 1 - i;
|
||||||
|
$('#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 {
|
||||||
|
console.log('Task N ' + data + ' is not checked on Fluence!')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('button').click(function () {
|
||||||
|
let id = $(this)[0].id.slice(-1);
|
||||||
|
let data = $('#state-id-' + id)[0].textContent;
|
||||||
|
|
||||||
|
if ($(this)[0].textContent === 'Challenge on Fluence!') {
|
||||||
|
contractInstance.taskDataById(data, function (err, result) {
|
||||||
|
let public_par = result.slice(0, 5);
|
||||||
|
let proof = result.slice(5, 13);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
31
frontend/package.json
Normal file
31
frontend/package.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
35
frontend/webpack.config.js
Normal file
35
frontend/webpack.config.js
Normal file
@ -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: "production",
|
||||||
|
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()
|
||||||
|
]
|
||||||
|
};
|
@ -19,6 +19,9 @@ contract Lazy is Structs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Task[] public tasks;
|
Task[] public tasks;
|
||||||
|
function tasksNum() external view returns(uint) {
|
||||||
|
return tasks.length;
|
||||||
|
}
|
||||||
|
|
||||||
uint256 public stake;
|
uint256 public stake;
|
||||||
IVerifier public verifier;
|
IVerifier public verifier;
|
||||||
@ -65,6 +68,28 @@ contract Lazy is Structs {
|
|||||||
msg.sender.transfer(stake);
|
msg.sender.transfer(stake);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function taskDataById(uint id) external view returns(
|
||||||
|
uint[13] memory data
|
||||||
|
) {
|
||||||
|
Task memory task = tasks[id];
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function last5Timestamps() view external returns (uint256[5] memory result) {
|
function last5Timestamps() view external returns (uint256[5] memory result) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user