mirror of
https://github.com/tornadocash/tornado-cli.git
synced 2024-11-22 01:37:08 +01:00
add taskSplit, HD-note
This commit is contained in:
parent
f86c74b9fc
commit
bc8907c200
142
cli.js
142
cli.js
@ -21,6 +21,8 @@ const program = require('commander');
|
|||||||
const { GasPriceOracle } = require('gas-price-oracle');
|
const { GasPriceOracle } = require('gas-price-oracle');
|
||||||
const SocksProxyAgent = require('socks-proxy-agent');
|
const SocksProxyAgent = require('socks-proxy-agent');
|
||||||
const is_ip_private = require('private-ip');
|
const is_ip_private = require('private-ip');
|
||||||
|
const bip39 = require("bip39");
|
||||||
|
const { hdkey } = require('ethereumjs-wallet');
|
||||||
|
|
||||||
let web3, torPort, tornado, tornadoContract, tornadoInstance, circuit, proving_key, groth16, erc20, senderAccount, netId, netName, netSymbol, doNotSubmitTx, multiCall, privateRpc, subgraph;
|
let web3, torPort, tornado, tornadoContract, tornadoInstance, circuit, proving_key, groth16, erc20, senderAccount, netId, netName, netSymbol, doNotSubmitTx, multiCall, privateRpc, subgraph;
|
||||||
let MERKLE_TREE_HEIGHT, ETH_AMOUNT, TOKEN_AMOUNT, PRIVATE_KEY;
|
let MERKLE_TREE_HEIGHT, ETH_AMOUNT, TOKEN_AMOUNT, PRIVATE_KEY;
|
||||||
@ -98,11 +100,11 @@ async function generateTransaction(to, encodedData, value = 0) {
|
|||||||
|
|
||||||
async function estimateGas() {
|
async function estimateGas() {
|
||||||
const fetchedGas = await web3.eth.estimateGas({
|
const fetchedGas = await web3.eth.estimateGas({
|
||||||
from : senderAccount,
|
from: senderAccount,
|
||||||
to : to,
|
to: to,
|
||||||
value : value,
|
value: value,
|
||||||
nonce : nonce,
|
nonce: nonce,
|
||||||
data : encodedData
|
data: encodedData
|
||||||
});
|
});
|
||||||
const bumped = Math.floor(fetchedGas * 1.3);
|
const bumped = Math.floor(fetchedGas * 1.3);
|
||||||
return web3.utils.toHex(bumped);
|
return web3.utils.toHex(bumped);
|
||||||
@ -117,32 +119,32 @@ async function generateTransaction(to, encodedData, value = 0) {
|
|||||||
// Generate EIP-1559 transaction
|
// Generate EIP-1559 transaction
|
||||||
if (netId == 1) {
|
if (netId == 1) {
|
||||||
return {
|
return {
|
||||||
to : to,
|
to: to,
|
||||||
value : value,
|
value: value,
|
||||||
nonce : nonce,
|
nonce: nonce,
|
||||||
maxFeePerGas : gasPrice,
|
maxFeePerGas: gasPrice,
|
||||||
maxPriorityFeePerGas : web3.utils.toHex(web3.utils.toWei('3', 'gwei')),
|
maxPriorityFeePerGas: web3.utils.toHex(web3.utils.toWei('3', 'gwei')),
|
||||||
gas : gasLimit,
|
gas: gasLimit,
|
||||||
data : encodedData
|
data: encodedData
|
||||||
}
|
}
|
||||||
} else if (netId == 5 || netId == 137 || netId == 43114) {
|
} else if (netId == 5 || netId == 137 || netId == 43114) {
|
||||||
return {
|
return {
|
||||||
to : to,
|
to: to,
|
||||||
value : value,
|
value: value,
|
||||||
nonce : nonce,
|
nonce: nonce,
|
||||||
maxFeePerGas : gasPrice,
|
maxFeePerGas: gasPrice,
|
||||||
maxPriorityFeePerGas : gasPrice,
|
maxPriorityFeePerGas: gasPrice,
|
||||||
gas : gasLimit,
|
gas: gasLimit,
|
||||||
data : encodedData
|
data: encodedData
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
to : to,
|
to: to,
|
||||||
value : value,
|
value: value,
|
||||||
nonce : nonce,
|
nonce: nonce,
|
||||||
gasPrice : gasPrice,
|
gasPrice: gasPrice,
|
||||||
gas : gasLimit,
|
gas: gasLimit,
|
||||||
data : encodedData
|
data: encodedData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,7 +270,7 @@ async function deposit({ currency, amount, commitmentNote }) {
|
|||||||
await printERC20Balance({ address: senderAccount, name: 'Sender account' });
|
await printERC20Balance({ address: senderAccount, name: 'Sender account' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!commitmentNote) {
|
if (!commitmentNote) {
|
||||||
return noteString;
|
return noteString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -815,8 +817,8 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
const cachedEvents = loadCachedEvents({ type, currency, amount });
|
const cachedEvents = loadCachedEvents({ type, currency, amount });
|
||||||
const startBlock = cachedEvents.lastBlock + 1;
|
const startBlock = cachedEvents.lastBlock + 1;
|
||||||
|
|
||||||
console.log("Loaded cached",amount,currency.toUpperCase(),type,"events for",startBlock,"block");
|
console.log("Loaded cached", amount, currency.toUpperCase(), type, "events for", startBlock, "block");
|
||||||
console.log("Fetching",amount,currency.toUpperCase(),type,"events for",netName,"network");
|
console.log("Fetching", amount, currency.toUpperCase(), type, "events for", netName, "network");
|
||||||
|
|
||||||
async function syncEvents() {
|
async function syncEvents() {
|
||||||
try {
|
try {
|
||||||
@ -854,7 +856,7 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapLatestEvents() {
|
function mapLatestEvents() {
|
||||||
if (type === "deposit"){
|
if (type === "deposit") {
|
||||||
mapDepositEvents();
|
mapDepositEvents();
|
||||||
} else {
|
} else {
|
||||||
mapWithdrawEvents();
|
mapWithdrawEvents();
|
||||||
@ -873,7 +875,7 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
toBlock: j,
|
toBlock: j,
|
||||||
}).then(r => { fetchedEvents = fetchedEvents.concat(r); console.log("Fetched", amount, currency.toUpperCase(), type, "events to block:", j) }, err => { console.error(i + " failed fetching", type, "events from node", err); process.exit(1); }).catch(console.log);
|
}).then(r => { fetchedEvents = fetchedEvents.concat(r); console.log("Fetched", amount, currency.toUpperCase(), type, "events to block:", j) }, err => { console.error(i + " failed fetching", type, "events from node", err); process.exit(1); }).catch(console.log);
|
||||||
|
|
||||||
if (type === "deposit"){
|
if (type === "deposit") {
|
||||||
mapDepositEvents();
|
mapDepositEvents();
|
||||||
} else {
|
} else {
|
||||||
mapWithdrawEvents();
|
mapWithdrawEvents();
|
||||||
@ -887,7 +889,7 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
const events = localEvents.concat(fetchedEvents);
|
const events = localEvents.concat(fetchedEvents);
|
||||||
await fs.writeFileSync(fileName, JSON.stringify(events, null, 2), 'utf8');
|
await fs.writeFileSync(fileName, JSON.stringify(events, null, 2), 'utf8');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error('Writing cache file failed:',error);
|
throw new Error('Writing cache file failed:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await fetchWeb3Events(i);
|
await fetchWeb3Events(i);
|
||||||
@ -1021,7 +1023,7 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
const events = localEvents.concat(fetchedEvents);
|
const events = localEvents.concat(fetchedEvents);
|
||||||
await fs.writeFileSync(fileName, JSON.stringify(events, null, 2), 'utf8');
|
await fs.writeFileSync(fileName, JSON.stringify(events, null, 2), 'utf8');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error('Writing cache file failed:',error);
|
throw new Error('Writing cache file failed:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,7 +1071,7 @@ async function fetchEvents({ type, currency, amount }) {
|
|||||||
const fileName = `./cache/${netName.toLowerCase()}/${type}s_${currency}_${amount}.json`;
|
const fileName = `./cache/${netName.toLowerCase()}/${type}s_${currency}_${amount}.json`;
|
||||||
const updatedEvents = await initJson(fileName);
|
const updatedEvents = await initJson(fileName);
|
||||||
const updatedBlock = updatedEvents[updatedEvents.length - 1].blockNumber;
|
const updatedBlock = updatedEvents[updatedEvents.length - 1].blockNumber;
|
||||||
console.log("Cache updated for Tornado",type,amount,currency,"instance to block",updatedBlock,"successfully");
|
console.log("Cache updated for Tornado", type, amount, currency, "instance to block", updatedBlock, "successfully");
|
||||||
console.log(`Total ${type}s:`, updatedEvents.length);
|
console.log(`Total ${type}s:`, updatedEvents.length);
|
||||||
return updatedEvents;
|
return updatedEvents;
|
||||||
}
|
}
|
||||||
@ -1529,4 +1531,76 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
// main();
|
||||||
|
|
||||||
|
function taskSplit({ amount, options }) {
|
||||||
|
options.sort().reverse()
|
||||||
|
optimalTask = {}
|
||||||
|
console.log("try to deposit ", amount, "via ", options)
|
||||||
|
console.log("optimal deposit are:")
|
||||||
|
for (var option of options) {
|
||||||
|
tmp = Math.floor(amount / option)
|
||||||
|
amount -= tmp * option
|
||||||
|
optimalTask[option] = tmp
|
||||||
|
console.log(tmp, "deposit via", option)
|
||||||
|
}
|
||||||
|
return optimalTask
|
||||||
|
}
|
||||||
|
|
||||||
|
function genCompactNote({ currency, amount, netId }) {
|
||||||
|
var mnemonic = bip39.generateMnemonic()
|
||||||
|
fs.writeFileSync(`./hd-torn-${currency}-${amount}-${netId}.txt`, mnemonic, 'utf8');
|
||||||
|
console.log("backup hd-torn note with seed: ", mnemonic)
|
||||||
|
console.log("this hierarchical deterministic note can generate multiple deposit.")
|
||||||
|
|
||||||
|
return mnemonic
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createMultipleDeposit({ mnemonic, amount }) {
|
||||||
|
let seed = bip39.mnemonicToSeedSync(mnemonic);
|
||||||
|
let hdwallet = hdkey.fromMasterSeed(seed);
|
||||||
|
let wallet_hdpath = "m/44'/60'/0'/0/";
|
||||||
|
|
||||||
|
let deposits = [];
|
||||||
|
for (let i = 0; i < amount; i++) {
|
||||||
|
|
||||||
|
let wallet1 = hdwallet.derivePath(wallet_hdpath + (i * 2)).getWallet();
|
||||||
|
let secretRaw = wallet1.getPrivateKey();
|
||||||
|
let secret = bigInt.leBuff2int(secretRaw.slice(1))
|
||||||
|
|
||||||
|
let wallet2 = hdwallet.derivePath(wallet_hdpath + (i * 2 + 1)).getWallet();
|
||||||
|
let nullifierRaw = wallet2.getPrivateKey();
|
||||||
|
let nullifier = bigInt.leBuff2int(nullifierRaw.slice(1))
|
||||||
|
|
||||||
|
let dep = createDeposit({ nullifier: nullifier, secret: secret })
|
||||||
|
deposits.push({ idx: i, deposit: dep });
|
||||||
|
|
||||||
|
}
|
||||||
|
return deposits;
|
||||||
|
}
|
||||||
|
|
||||||
|
function recoverDepositFromMnemonic({ mnemonic, idx }) {
|
||||||
|
let seed = bip39.mnemonicToSeedSync(mnemonic);
|
||||||
|
let hdwallet = hdkey.fromMasterSeed(seed);
|
||||||
|
let wallet_hdpath = "m/44'/60'/0'/0/";
|
||||||
|
let wallet1 = hdwallet.derivePath(wallet_hdpath + (idx * 2)).getWallet();
|
||||||
|
let secretRaw = wallet1.getPrivateKey();
|
||||||
|
let secret = bigInt.leBuff2int(secretRaw.slice(1))
|
||||||
|
let wallet2 = hdwallet.derivePath(wallet_hdpath + (idx * 2 + 1)).getWallet();
|
||||||
|
let nullifierRaw = wallet2.getPrivateKey();
|
||||||
|
let nullifier = bigInt.leBuff2int(nullifierRaw.slice(1))
|
||||||
|
|
||||||
|
let dep = createDeposit({ nullifier: nullifier, secret: secret })
|
||||||
|
return dep
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tasks = taskSplit({ amount: 420.69, options: [0.1, 1, 10, 100,] })
|
||||||
|
console.log(tasks)
|
||||||
|
const mnemonic = genCompactNote({ currency: "ETH", amount: '420.69', netId: 1 })
|
||||||
|
const amount = 3;
|
||||||
|
const deposits = createMultipleDeposit({ mnemonic, amount });
|
||||||
|
console.log(deposits);
|
||||||
|
console.log(recoverDepositFromMnemonic({ mnemonic, idx: 0 }))
|
||||||
|
console.log(recoverDepositFromMnemonic({ mnemonic, idx: 1 }))
|
||||||
|
Loading…
Reference in New Issue
Block a user