SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
07.12.2024

Lição: 258: Usando Tornado Cash

Tornado Cash é uma solução descentralizada de privacidade construída sobre o Ethereum que permite que os usuários enviem e recebam fundos sem revelar seu histórico de transações. Isso é alcançado através de provas de conhecimento zero que ocultam a origem e o destino dos fundos. Esta aula irá guiá-lo pelos conceitos básicos do Tornado Cash e mostrar como interagir com ele usando Solidity e JavaScript.

Entendendo o Tornado Cash

Antes de mergulharmos no código, é essencial entender como o Tornado Cash funciona:

  1. Depósitos: Os usuários depositam ETH ou tokens no contrato inteligente do Tornado Cash, gerando um recibo privado. Este recibo é crucial, pois permite que os usuários retirem seus depósitos posteriormente.

  2. Saques Anônimos: Para sacar fundos, os usuários devem apresentar seu recibo privado ao contrato inteligente do Tornado Cash. Essa etapa é realizada sem vincular o saque ao endereço do depósito.

  3. Provas de Conhecimento Zero: O anonimato é alcançado usando zk-SNARKs (provas succincts não interativas de conhecimento), que validam a transação sem revelar qualquer informação sobre o remetente ou o destinatário.

Configurando o Ambiente

Para interagir com os contratos inteligentes do Tornado Cash, certifique-se de ter as ferramentas necessárias:

  • Node.js e npm para gerenciamento de pacotes
  • Hardhat para desenvolvimento local em Ethereum
  • Ether.js ou Web3.js para interagir com o Ethereum

Você pode configurar um projeto Hardhat da seguinte forma:

mkdir tornado-cash-demo
cd tornado-cash-demo
npm init -y
npm install --save-dev hardhat
npx hardhat

Escolha "Criar um arquivo de configuração vazio hardhat.config.js", e seu ambiente de trabalho estará pronto.

Implantando o Contrato Inteligente Tornado Cash (Exemplo)

Para esta aula, ilustraremos uma versão simplificada de um contrato de depósito e retirada semelhante ao Tornado Cash. Abaixo está um contrato inteligente básico em Solidity.

TornadoCash.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract TornadoCash {
    struct Deposit {
        uint256 amount;
        bytes32 commitment;
    }

    mapping(address => Deposit) public deposits;

    event Deposited(address indexed user, bytes32 commitment);
    event Withdrawn(address indexed user, uint256 amount);

    function deposit(bytes32 _commitment) external payable {
        require(msg.value > 0, "Envie ETH para depositar");

        deposits[msg.sender] = Deposit(msg.value, _commitment);
        emit Deposited(msg.sender, _commitment);
    }

    function withdraw(uint256 _amount) external {
        Deposit storage userDeposit = deposits[msg.sender];
        require(userDeposit.amount >= _amount, "Fundos insuficientes");

        userDeposit.amount -= _amount;
        payable(msg.sender).transfer(_amount);
        emit Withdrawn(msg.sender, _amount);
    }
}

Explicação:

  • Estrutura de Depósito: Uma estrutura para armazenar o valor e o compromisso de cada usuário.
  • Mapeamento: Armazena os depósitos correspondentes ao endereço de cada usuário.
  • Eventos: Emite eventos para cada depósito e retirada para melhor transparência.
  • Função de Depósito: Aceita ETH e um compromisso (hash representando o depósito).
  • Função de Saque: Verifica o depósito do usuário e permite o saque de um montante especificado.

Interagindo com o Contrato Inteligente usando JavaScript

Uma vez que você tenha implantado seu contrato inteligente, pode interagir com ele usando Ether.js em um script. Abaixo está um exemplo de como depositar e retirar usando esta biblioteca.

interaction.js

const { ethers } = require("hardhat");

async function main() {
    const [deployer] = await ethers.getSigners();

    // Obtém o contrato implantado
    const TornadoCash = await ethers.getContractFactory("TornadoCash");
    const tornadoCash = await TornadoCash.deploy();
    await tornadoCash.deployed();

    console.log("TornadoCash implantado em:", tornadoCash.address);

    // Exemplo de Depósito
    const commitment = ethers.utils.formatBytes32String("Seu hash de compromisso");
    const depositTx = await tornadoCash.deposit(commitment, { value: ethers.utils.parseEther("1") });
    await depositTx.wait();
    console.log("Depositou 1 ETH com compromisso:", commitment);

    // Exemplo de Saque
    const withdrawTx = await tornadoCash.withdraw(ethers.utils.parseEther("1"));
    await withdrawTx.wait();
    console.log("Retirou 1 ETH");
}

main()
    .then(() => process.exit(0))
    .catch((error) => {
      console.error(error);
      process.exit(1);
});

Explicação:

  • Busca o endereço da carteira do deployador usando getSigners().
  • Implanta o contrato TornadoCash.
  • Chama a função deposit para enviar 1 ETH e fornecer um compromisso.
  • Por fim, demonstra como retirar o valor depositado.

Conclusão

Tornado Cash oferece uma abordagem inovadora para aprimorar a privacidade das transações no Ethereum. Ao usar contratos inteligentes e provas de conhecimento zero, os usuários podem depositar e retirar fundos de forma discreta, garantindo que suas atividades financeiras permaneçam confidenciais. Esta aula destacou uma implementação simples de um mecanismo de depósito e retirada inspirado no Tornado Cash, demonstrando os conceitos centrais por trás da privacidade nas transações em blockchain.

Experimente com o código e considere integrar zk-SNARKs para uma solução de privacidade completa! Boa codificação!

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!