process_withdraw.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import os
  2. from web3 import Web3
  3. import pandas as pd
  4. from typing import Any, Dict
  5. def main(args: Any):
  6. withdraw_file: str = os.path.join(args.data_dir, 'withdraw_transactions.csv')
  7. abi_file: str = os.path.join(args.data_dir, 'tornadocontracts_abi.csv')
  8. withdraw_df: pd.DataFrame = pd.read_csv(withdraw_file)
  9. addresses_df: pd.DataFrame = pd.read_csv(
  10. abi_file,
  11. names=['address', 'token', 'value', 'name', 'abi'],
  12. sep='|',
  13. )
  14. contracts: pd.DataFrame = get_contracts(addresses_df)
  15. withdraw_df['recipient_address'] = withdraw_df.apply(
  16. lambda row: recipient_address(row, contracts), axis=1)
  17. out_path: str = os.path.join(args.data_dir, 'tornado_withdraw_df.csv')
  18. withdraw_df.to_csv(out_path)
  19. def get_contracts(data: pd.DataFrame):
  20. # creates contract object given it address and abi
  21. w3: Web3 = Web3(Web3.HTTPProvider('https://cloudflare-eth.com'))
  22. contracts: Dict[str, Any] = {}
  23. for _, row in data.iterrows():
  24. address: str = row['address']
  25. contracts[address] = w3.eth.contract(
  26. address=w3.toChecksumAddress(address),
  27. abi=eval(row['abi']),
  28. )
  29. return contracts
  30. def recipient_address(row: pd.Series, contracts: Dict[str, Any]):
  31. to_address: str = row['to_address']
  32. input_data: str = row['input']
  33. _, func_params = contracts[to_address].decode_function_input(input_data)
  34. return func_params["_recipient"]
  35. if __name__ == "__main__":
  36. from argparse import ArgumentParser
  37. parser: ArgumentParser = ArgumentParser()
  38. parser.add_argument('data_dir', type=str, help='path to tornado cash data')
  39. args: Any = parser.parse_args()
  40. main(args)