mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
withdraw
This commit is contained in:
parent
4c510b186a
commit
72e2d39973
@ -64,8 +64,8 @@ contract TornadoPool is ReentrancyGuard {
|
|||||||
uint256(_outputCommitments[1]),
|
uint256(_outputCommitments[1]),
|
||||||
_extAmount,
|
_extAmount,
|
||||||
_fee,
|
_fee,
|
||||||
uint256(_relayer),
|
uint256(_recipient),
|
||||||
uint256(_recipient)
|
uint256(_relayer)
|
||||||
]), "Invalid transaction proof");
|
]), "Invalid transaction proof");
|
||||||
|
|
||||||
currentRoot = _newRoot;
|
currentRoot = _newRoot;
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
"build:circuit:bin": "node node_modules/websnark/tools/buildpkey.js -i build/circuits/transaction_proving_key.json -o build/circuits/transaction_proving_key.bin",
|
"build:circuit:bin": "node node_modules/websnark/tools/buildpkey.js -i build/circuits/transaction_proving_key.json -o build/circuits/transaction_proving_key.bin",
|
||||||
"build:circuit:contract": "npx snarkjs generateverifier -v build/circuits/Verifier.sol --vk build/circuits/transaction_verification_key.json",
|
"build:circuit:contract": "npx snarkjs generateverifier -v build/circuits/Verifier.sol --vk build/circuits/transaction_verification_key.json",
|
||||||
"build:circuit": "mkdir -p build/circuits && npm run build:circuit:compile && npm run build:circuit:setup && npm run build:circuit:bin && npm run build:circuit:contract",
|
"build:circuit": "mkdir -p build/circuits && npm run build:circuit:compile && npm run build:circuit:setup && npm run build:circuit:bin && npm run build:circuit:contract",
|
||||||
|
"build:contract": "npx truffle compile",
|
||||||
|
"build": "npm run build:circuit && npm run build:contract",
|
||||||
"migrate:dev": "npx truffle migrate --network development --reset"
|
"migrate:dev": "npx truffle migrate --network development --reset"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
77
src/index.js
77
src/index.js
@ -15,6 +15,7 @@ const hasher = new Hasher()
|
|||||||
|
|
||||||
const MERKLE_TREE_HEIGHT = 5
|
const MERKLE_TREE_HEIGHT = 5
|
||||||
const RPC_URL = 'http://localhost:8545'
|
const RPC_URL = 'http://localhost:8545'
|
||||||
|
const FIELD_SIZE = '21888242871839275222246405745257275088548364400416034343698204186575808495617'
|
||||||
|
|
||||||
/** Generate random number of specified byte length */
|
/** Generate random number of specified byte length */
|
||||||
const rbigint = (nbytes = 31) => bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
const rbigint = (nbytes = 31) => bigInt.leBuff2int(crypto.randomBytes(nbytes))
|
||||||
@ -179,6 +180,8 @@ async function transact(txOutput) {
|
|||||||
inputs: [input1, createZeroUtxo(fromPrivkey(txOutput.privkey))],
|
inputs: [input1, createZeroUtxo(fromPrivkey(txOutput.privkey))],
|
||||||
outputs: [createOutput(txOutput.amount / 4, keypair.pubkey), createOutput(txOutput.amount * 3 / 4, txOutput.pubkey)], // todo shuffle
|
outputs: [createOutput(txOutput.amount / 4, keypair.pubkey), createOutput(txOutput.amount * 3 / 4, txOutput.pubkey)], // todo shuffle
|
||||||
}
|
}
|
||||||
|
tx.outputs[0].privkey = keypair.privkey
|
||||||
|
tx.outputs[1].privkey = txOutput.privkey
|
||||||
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])
|
||||||
@ -233,6 +236,79 @@ async function transact(txOutput) {
|
|||||||
return tx.outputs[0]
|
return tx.outputs[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function withdraw(txOutput) {
|
||||||
|
console.log('txOutput', txOutput)
|
||||||
|
const tree = await buildMerkleTree()
|
||||||
|
const oldRoot = await tree.root()
|
||||||
|
|
||||||
|
const index = await tree.getIndexByElement(toHex(txOutput.commitment))
|
||||||
|
console.log('index', index)
|
||||||
|
const { path_elements, path_index } = await tree.path(index)
|
||||||
|
console.log('path_index', path_index)
|
||||||
|
txOutput.merklePathElements = path_elements
|
||||||
|
const input1 = createInput(txOutput)
|
||||||
|
const fakeKeypair = randomKeypair()
|
||||||
|
const tx = {
|
||||||
|
inputs: [input1, createZeroUtxo(fromPrivkey(txOutput.privkey))],
|
||||||
|
outputs: [createZeroUtxo(fakeKeypair), createZeroUtxo(fakeKeypair)], // todo shuffle
|
||||||
|
}
|
||||||
|
await insertOutput(tree, tx.outputs[0])
|
||||||
|
await insertOutput(tree, tx.outputs[1])
|
||||||
|
|
||||||
|
let input = {
|
||||||
|
root: oldRoot,
|
||||||
|
newRoot: await tree.root(),
|
||||||
|
inputNullifier: [tx.inputs[0].nullifier, tx.inputs[1].nullifier],
|
||||||
|
outputCommitment: [tx.outputs[0].commitment, tx.outputs[1].commitment],
|
||||||
|
extAmount: bigInt(FIELD_SIZE).sub(bigInt(txOutput.amount)),
|
||||||
|
fee: 0,
|
||||||
|
recipient: '0xc2Ba33d4c0d2A92fb4f1a07C273c5d21E688Eb48',
|
||||||
|
relayer: 0,
|
||||||
|
|
||||||
|
// private inputs
|
||||||
|
privateKey: tx.inputs[0].privkey,
|
||||||
|
|
||||||
|
// data for 2 transaction inputs
|
||||||
|
inAmount: [tx.inputs[0].amount, tx.inputs[1].amount],
|
||||||
|
inBlinding: [tx.inputs[0].blinding, tx.inputs[1].blinding],
|
||||||
|
inPathIndices: [merklePathIndicesToBigint(tx.inputs[0].merklePathIndices), merklePathIndicesToBigint(tx.inputs[1].merklePathIndices)],
|
||||||
|
inPathElements: [tx.inputs[0].merklePathElements, tx.inputs[1].merklePathElements],
|
||||||
|
|
||||||
|
// data for 2 transaction outputs
|
||||||
|
outAmount: [tx.outputs[0].amount, tx.outputs[1].amount],
|
||||||
|
outBlinding: [tx.outputs[0].blinding, tx.outputs[1].blinding],
|
||||||
|
outPubkey: [tx.outputs[0].pubkey, tx.outputs[1].pubkey],
|
||||||
|
outPathIndices: merklePathIndicesToBigint(tx.outputs[0].merklePathIndices.slice(1)),
|
||||||
|
outPathElements: tx.outputs[0].merklePathElements.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('WITHDRAW input', input)
|
||||||
|
|
||||||
|
console.log('Generating SNARK proof...')
|
||||||
|
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key)
|
||||||
|
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||||
|
|
||||||
|
const args = [
|
||||||
|
toHex(input.root),
|
||||||
|
toHex(input.newRoot),
|
||||||
|
[toHex(tx.inputs[0].nullifier), toHex(tx.inputs[1].nullifier)],
|
||||||
|
[toHex(tx.outputs[0].commitment), toHex(tx.outputs[1].commitment)],
|
||||||
|
toHex(input.extAmount),
|
||||||
|
toHex(input.fee),
|
||||||
|
toHex(input.recipient, 20),
|
||||||
|
toHex(input.relayer, 20),
|
||||||
|
]
|
||||||
|
|
||||||
|
console.log('args', args)
|
||||||
|
|
||||||
|
console.log('Sending withdraw transaction...')
|
||||||
|
const receipt = await contract.methods.transaction(proof, ...args).send({ from: web3.eth.defaultAccount, gas: 1e6 })
|
||||||
|
console.log(`Receipt ${receipt.transactionHash}`)
|
||||||
|
|
||||||
|
let bal = await web3.eth.getBalance('0xc2Ba33d4c0d2A92fb4f1a07C273c5d21E688Eb48')
|
||||||
|
console.log('balance', bal)
|
||||||
|
}
|
||||||
|
|
||||||
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')
|
||||||
@ -245,6 +321,7 @@ async function main() {
|
|||||||
|
|
||||||
const txOutput = await deposit()
|
const txOutput = await deposit()
|
||||||
const txOutput1 = await transact(txOutput)
|
const txOutput1 = await transact(txOutput)
|
||||||
|
await withdraw(txOutput1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user