fix indentation

This commit is contained in:
Alexey 2020-04-09 22:12:45 +03:00
parent a772d76829
commit 0edd6d237c
3 changed files with 140 additions and 97 deletions

View File

@ -2,7 +2,7 @@ root = true
[*] [*]
indent_style = space indent_style = space
indent_size = 4 indent_size = 2
end_of_line = lf end_of_line = lf
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true

39
.eslintrc.json Normal file
View File

@ -0,0 +1,39 @@
{
"env": {
"node": true,
"browser": true,
"es6": true,
"mocha": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
],
"object-curly-spacing": [
"error",
"always"
],
"require-await": "error"
}
}

View File

@ -25,149 +25,153 @@ const toHex = (number, length = 32) => '0x' + (number instanceof Buffer ? number
function merklePathIndicesToBigint(indexArray) { function merklePathIndicesToBigint(indexArray) {
let result = 0 let result = 0
for(let item of indexArray.slice().reverse()) { for(let item of indexArray.slice().reverse()) {
result = (result << 1) + item result = (result << 1) + item
} }
return result return result
} }
function fromPrivkey(privkey) { function fromPrivkey(privkey) {
return { return {
privkey, privkey,
pubkey: hasher.hashArray([privkey]), pubkey: hasher.hashArray([privkey]),
} }
} }
function randomKeypair() { function randomKeypair() {
return fromPrivkey(rbigint()) return fromPrivkey(rbigint())
} }
function createZeroUtxo(keypair) { function createZeroUtxo(keypair) {
return createUtxo( return createUtxo(
0, 0,
rbigint(), rbigint(),
keypair.pubkey, keypair.pubkey,
keypair.privkey, keypair.privkey,
Array(MERKLE_TREE_HEIGHT).fill(0), Array(MERKLE_TREE_HEIGHT).fill(0),
Array(MERKLE_TREE_HEIGHT).fill(0) Array(MERKLE_TREE_HEIGHT).fill(0)
) )
} }
function createOutput(amount, pubkey) { function createOutput(amount, pubkey) {
if (!pubkey) { if (!pubkey) {
throw new Error('no pubkey') throw new Error('no pubkey')
} }
return createUtxo(amount, rbigint(), pubkey) return createUtxo(amount, rbigint(), pubkey)
} }
function createInput(amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements) { function createInput(amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements) {
return createUtxo(amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements) return createUtxo(amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements)
} }
/// unsafe function without sanity checks /// unsafe function without sanity checks
function createUtxo(amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements) { function createUtxo(amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements) {
let utxo = { amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements } let utxo = { amount, blinding, pubkey, privkey, merklePathIndices, merklePathElements }
utxo.commitment = hasher.hashArray([amount, blinding, pubkey]) utxo.commitment = hasher.hashArray([amount, blinding, pubkey])
if (privkey) { if (privkey) {
utxo.nullifier = hasher.hashArray([utxo.commitment, merklePathIndicesToBigint(merklePathIndices), privkey]) utxo.nullifier = hasher.hashArray([utxo.commitment, merklePathIndicesToBigint(merklePathIndices), privkey])
} }
return utxo return utxo
} }
function createDeposit(amount, pubkey) { function createDeposit(amount, pubkey) {
const keypair = randomKeypair() const keypair = randomKeypair()
const tx = { const tx = {
inputs: [createZeroUtxo(keypair), createZeroUtxo(keypair)], inputs: [createZeroUtxo(keypair), createZeroUtxo(keypair)],
outputs: [createOutput(amount, pubkey), createZeroUtxo(keypair)], // todo shuffle outputs: [createOutput(amount, pubkey), createZeroUtxo(keypair)], // todo shuffle
} }
return tx; return tx
} }
async function buildMerkleTree() { async function buildMerkleTree() {
console.log('Getting contract state...') console.log('Getting contract state...')
const events = await contract.getPastEvents('NewCommitment', { fromBlock: 0, toBlock: 'latest' }) const events = await contract.getPastEvents('NewCommitment', { fromBlock: 0, toBlock: 'latest' })
const leaves = events const leaves = events
.sort((a, b) => a.returnValues.index - b.returnValues.index) // todo sort by event date .sort((a, b) => a.returnValues.index - b.returnValues.index) // todo sort by event date
.map(e => e.returnValues.commitment) .map(e => e.returnValues.commitment)
return new MerkleTree(MERKLE_TREE_HEIGHT, leaves) return new MerkleTree(MERKLE_TREE_HEIGHT, leaves)
} }
async function insertOutput(tree, output) { async function insertOutput(tree, output) {
await tree.insert(output.commitment) await tree.insert(output.commitment)
let { path_elements, path_index } = await tree.path(tree.totalElements - 1) let { path_elements, path_index } = await tree.path(tree.totalElements - 1)
output.merklePathIndices = path_index output.merklePathIndices = path_index
output.merklePathElements = path_elements output.merklePathElements = path_elements
} }
async function deposit() { async function deposit() {
const amount = 1e6; const amount = 1e6
const tree = await buildMerkleTree() const tree = await buildMerkleTree()
const oldRoot = await tree.root() const oldRoot = await tree.root()
const keypair = randomKeypair() const keypair = randomKeypair()
const tx = createDeposit(amount, keypair.pubkey) const tx = createDeposit(amount, keypair.pubkey)
await insertOutput(tree, tx.outputs[0]) await insertOutput(tree, tx.outputs[0])
await insertOutput(tree, tx.outputs[1]) await insertOutput(tree, tx.outputs[1])
console.log('Note', tx.outputs[0]) console.log('Note', tx.outputs[0])
let input = { let input = {
root: oldRoot, root: oldRoot,
newRoot: await tree.root(), newRoot: await tree.root(),
inputNullifier: [tx.inputs[0].nullifier, tx.inputs[1].nullifier], inputNullifier: [tx.inputs[0].nullifier, tx.inputs[1].nullifier],
outputCommitment: [tx.outputs[0].commitment, tx.outputs[1].commitment], outputCommitment: [tx.outputs[0].commitment, tx.outputs[1].commitment],
extAmount: amount, extAmount: amount,
fee: 0, fee: 0,
recipient: 0, recipient: 0,
relayer: 0, relayer: 0,
// private inputs // private inputs
privateKey: tx.inputs[0].privkey, privateKey: tx.inputs[0].privkey,
// data for 2 transaction inputs // data for 2 transaction inputs
inAmount: [tx.inputs[0].amount, tx.inputs[1].amount], inAmount: [tx.inputs[0].amount, tx.inputs[1].amount],
inBlinding: [tx.inputs[0].blinding, tx.inputs[1].blinding], inBlinding: [tx.inputs[0].blinding, tx.inputs[1].blinding],
inPathIndices: [merklePathIndicesToBigint(tx.inputs[0].merklePathIndices), merklePathIndicesToBigint(tx.inputs[1].merklePathIndices)], inPathIndices: [merklePathIndicesToBigint(tx.inputs[0].merklePathIndices), merklePathIndicesToBigint(tx.inputs[1].merklePathIndices)],
inPathElements: [tx.inputs[0].merklePathElements, tx.inputs[1].merklePathElements], inPathElements: [tx.inputs[0].merklePathElements, tx.inputs[1].merklePathElements],
// data for 2 transaction outputs // data for 2 transaction outputs
outAmount: [tx.outputs[0].amount, tx.outputs[1].amount], outAmount: [tx.outputs[0].amount, tx.outputs[1].amount],
outBlinding: [tx.outputs[0].blinding, tx.outputs[1].blinding], outBlinding: [tx.outputs[0].blinding, tx.outputs[1].blinding],
outPubkey: [tx.outputs[0].pubkey, tx.outputs[1].pubkey], outPubkey: [tx.outputs[0].pubkey, tx.outputs[1].pubkey],
outPathIndices: merklePathIndicesToBigint(tx.outputs[0].merklePathIndices.slice(1)), outPathIndices: merklePathIndicesToBigint(tx.outputs[0].merklePathIndices.slice(1)),
outPathElements: tx.outputs[0].merklePathElements.slice(1) outPathElements: tx.outputs[0].merklePathElements.slice(1)
} }
console.log('input', JSON.stringify(stringifyBigInts(input))) console.log('input', JSON.stringify(stringifyBigInts(input)))
console.log('Generating SNARK proof...') console.log('Generating SNARK proof...')
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
const { proof } = websnarkUtils.toSolidityInput(proofData) const { proof } = websnarkUtils.toSolidityInput(proofData)
const args = [ const args = [
toHex(input.root), toHex(input.root),
toHex(input.newRoot), toHex(input.newRoot),
[toHex(tx.inputs[0].nullifier), toHex(tx.inputs[1].nullifier)], [toHex(tx.inputs[0].nullifier), toHex(tx.inputs[1].nullifier)],
[toHex(tx.outputs[0].commitment), toHex(tx.outputs[1].commitment)], [toHex(tx.outputs[0].commitment), toHex(tx.outputs[1].commitment)],
toHex(amount), toHex(amount),
toHex(input.fee), toHex(input.fee),
toHex(input.recipient, 20), toHex(input.recipient, 20),
toHex(input.relayer, 20), toHex(input.relayer, 20),
] ]
console.log('Sending deposit transaction...')
const receipt = await contract.methods.transaction(proof, ...args).send({ value: amount, from: web3.eth.defaultAccount, gas: 1e6 })
console.log(`Receipt ${receipt.transactionHash}`)
}
async function transact() {
console.log('Sending deposit transaction...')
const receipt = await contract.methods.transaction(proof, ...args).send({ value: amount, from: web3.eth.defaultAccount, gas: 1e6 })
console.log(`Receipt ${receipt.transactionHash}`)
} }
async function main() { async function main() {
web3 = new Web3(new Web3.providers.HttpProvider(RPC_URL, { timeout: 5 * 60 * 1000 }), null, { transactionConfirmationBlocks: 1 }) web3 = new Web3(new Web3.providers.HttpProvider(RPC_URL, { timeout: 5 * 60 * 1000 }), null, { transactionConfirmationBlocks: 1 })
circuit = require('../build/circuits/transaction.json') circuit = require('../build/circuits/transaction.json')
proving_key = fs.readFileSync('../build/circuits/transaction_proving_key.bin').buffer proving_key = fs.readFileSync('../build/circuits/transaction_proving_key.bin').buffer
groth16 = await buildGroth16() groth16 = await buildGroth16()
netId = await web3.eth.net.getId() netId = await web3.eth.net.getId()
const contractData = require('../build/contracts/TornadoPool.json') const contractData = require('../build/contracts/TornadoPool.json')
contract = new web3.eth.Contract(contractData.abi, contractData.networks[netId].address) contract = new web3.eth.Contract(contractData.abi, contractData.networks[netId].address)
web3.eth.defaultAccount = (await web3.eth.getAccounts())[0] web3.eth.defaultAccount = (await web3.eth.getAccounts())[0]
await deposit() await deposit()
} }