Série de Segurança Web3: É possível recuperar fundos enviados por engano para outra blockchain?

No mundo das criptomoedas, um clique por engano pode desencadear um “desastre digital”. Um dos pesadelos mais comuns é enviar ativos para a blockchain errada. Por exemplo, querer enviar ETH para um endereço na rede de testes Sepolia do Ethereum, mas acidentalmente enviá-lo para um endereço na rede principal do Ethereum. Nesses casos, ainda é possível recuperar os fundos enviados por engano na rede principal do Ethereum? A possibilidade de recuperar ativos depende do tipo de endereço de destino. Este artigo analisará diferentes cenários.

1. Cenário 1: O endereço de recebimento é EOA

EOA (Conta Externamente Controlada) é o que chamamos de uma carteira comum controlada diretamente por uma chave privada ou frase-semente.

Pré-requisitos para recuperar ativos:

  • Você enviou os ativos para um endereço EOA.
  • Você possui a chave privada ou frase-semente desse endereço EOA de destino. (Normalmente, é outro endereço de sua carteira, ou de um amigo, que esteja disposto a colaborar).
  • A cadeia de destino é compatível com EVM.

Método para recuperar ativos:

O detentor da chave privada do endereço EOA de recebimento pode simplesmente retirar os fundos na cadeia de destino.

2. Cenário 2: O endereço de recebimento é um contrato

Este é um dos cenários mais desesperadores. Como o endereço de um contrato inteligente não é gerado por uma chave privada, ninguém possui a chave privada do contrato inteligente, portanto, não é possível controlá-lo como um EOA. Além disso, se o contrato não tiver uma função de resgate pré-programada para lidar com “transferências incorretas de ativos”, os fundos enviados por engano podem ficar permanentemente bloqueados no contrato, sem possibilidade de retirada.

No entanto, em certas circunstâncias, ainda há uma esperança. A seguir, construiremos um cenário onde ETH fica bloqueado na rede principal do Ethereum, e explicaremos como resgatar esses fundos.

2.1. Introdução ao cenário

Resumidamente, neste cenário, o usuário pretendia interagir com um contrato na rede de testes Sepolia, enviando ETH para cunhar tokens, mas ao iniciar a transação, conectou-se erroneamente à rede principal, resultando no ETH sendo bloqueado no contrato da rede principal. O processo de construção do cenário é o seguinte:

1. Na rede de testes Ethereum Sepolia, o projeto (EOA) implantou um contrato de implementação, suponha que esse contrato tenha como função principal aceitar ETH dos usuários para cunhar tokens AToken, com um código semelhante à função mintTokens. O endereço de implantação é A. É importante notar que, em A, não há uma função que permita extrair ETH diretamente.

2. Na rede de testes Ethereum Sepolia, o projeto (EOA) implantou um contrato de fábrica (factory), cuja função é, usando o endereço do contrato de implementação fornecido e um valor salt, implantar um contrato proxy (como o método deployProxyByImplementation), que aponta para o contrato de implementação. O endereço de implantação é B. Aqui, ao chamar a função deployProxyByImplementation, passando o endereço do contrato A como _implementation, um contrato proxy apontando para A é implantado, com endereço C.

3. O usuário deseja cunhar AToken na rede de testes Sepolia enviando ETH, e assim, faz uma chamada ao contrato proxy C. Normalmente, o contrato proxy C chamaria a função mintTokens do contrato A para completar a operação. No entanto, o usuário conectou-se erroneamente à rede principal, e enviou ETH diretamente para o endereço C na rede principal. Neste momento, o endereço C na rede principal não possui contrato implantado, nem alguém controla sua chave privada, portanto, o ETH do usuário fica temporariamente bloqueado nesse endereço C na rede principal.

2.2. Pontos-chave

Antes de apresentar a solução de resgate, é importante entender alguns conceitos básicos necessários.

2.2.1. create & create2

create e create2 são duas formas comuns de implantar contratos em Solidity.

  • create implanta um contrato cujo endereço é determinado pelo endereço do criador e seu nonce (contador de transações), independentemente do conteúdo do contrato.
  • create2 calcula o endereço do contrato com base em quatro parâmetros: 0xff, o endereço do contrato que está criando, o valor salt (confusão), e o bytecode de criação do contrato (init_code). O endereço resultante depende desses parâmetros, não do conteúdo do contrato.

2.2.2. Contratos Proxy Mínimos (Clones)

https://docs.openzeppelin.com/contracts/4.x/api/proxy#clones

Contratos proxy mínimos, também chamados de clones, têm como ideia central implantar um contrato proxy de baixo custo (Gas), que aponta para um contrato de implementação específico. No contrato Clones, é possível usar create ou create2 para implantar o proxy, por exemplo, usando a função cloneDeterministic, que emprega create2.

Na função cloneDeterministic, o bytecode do proxy é bem curto, por exemplo: 0x363d3d373d3d3d363d73<endereço do contrato de implementação>5af43d82803e903d91602b57fd5bf3, onde o endereço do contrato de implementação é codificado diretamente no bytecode. Todas as chamadas ao proxy irão delegatecall para o contrato de implementação.

Ao usar cloneDeterministic, o endereço do proxy é calculado com base no endereço do criador, o salt, e o endereço do contrato de implementação, sendo independente do bytecode do contrato de implementação.

![])https://img-cdn.gateio.im/webp-social/moments-628ce0ce97dbf40349dc8b7a0c07eab3.webp(

)# 2.3. Solução de resgate

A seguir, explicamos como resgatar ETH que está na conta C na rede principal. A ideia principal é implantar um contrato na rede principal no endereço C, que assuma o controle da conta C e possa retirar os ETH bloqueados. Os passos específicos são:

![]###https://img-cdn.gateio.im/webp-social/moments-22428dd6bb1fbd62d2205538c0cc6c92.webp(

1. Implantar na rede principal um contrato de fábrica com o mesmo endereço B usado na rede de testes. É necessário que o endereço do contrato de fábrica seja o mesmo, pois o endereço do proxy será calculado com base nele ao usar cloneDeterministic. Para isso, é preciso obter o nonce do deployer (proprietário) na rede de testes, e na rede principal, avançar o nonce do proprietário até o mesmo valor, de modo que o contrato de fábrica seja implantado no mesmo endereço B.

2. Implantar na rede principal o contrato de implementação com o mesmo endereço A usado na rede de testes. Como o endereço do proxy é calculado com base no salt e no endereço do contrato de implementação, basta implantar um contrato qualquer em A — seu conteúdo não afeta o endereço do proxy. Assim, podemos implantar um contrato que permita extrair ETH, por exemplo:

// Exemplo de contrato para extrair ETH
contract Extractor {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    function withdraw() external {
        require(msg.sender == owner, "Somente o proprietário pode retirar");
        payable(owner).transfer(address(this).balance);
    }

    // Função para receber ETH
    receive() external payable {}
}

Na rede de testes, o contrato A foi implantado pelo projeto (EOA), portanto, seu endereço depende do criador e do nonce. Na rede principal, basta ajustar o nonce do proprietário até o valor correspondente ao nonce na rede de testes, e implantar o contrato A.

![])https://img-cdn.gateio.im/webp-social/moments-75bfcbe9932d6fff8befe5ac282e022d.webp#最小代理合约(Clones)#

3. Implantar na rede principal o proxy C com o mesmo endereço C da rede de testes. Observando a transação de implantação do proxy C na rede de testes, obtém-se o salt. Com esse salt, chama-se a função deployProxyByImplementation do contrato de fábrica B, passando o endereço do contrato A e o salt, para implantar o proxy C na rede principal.

4. Executar a retirada de ETH do contrato proxy C na rede principal. O proprietário (EOA) chama a função withdraw do proxy C, indicando o destinatário, e assim, recupera o ETH bloqueado no proxy, devolvendo ao usuário.

(# 2.4. Resumo

Como visto, a recuperação de fundos depende de várias condições, como o nonce do deployer na cadeia de destino não ter sido usado, o contrato bloqueador possuir uma função de retirada, ou ser possível implantar funções de retirada por upgrade ou proxies como Clones. Portanto, é fundamental verificar cuidadosamente cada transação antes de interagir com contratos. Pode-se usar ferramentas de análise de vulnerabilidades, como o AI SCAN da ZAN, para verificar a segurança do contrato. Se os fundos ficarem presos, não entre em pânico: entre em contato com a equipe de auditoria de contratos da ZAN para tentar resgatar os fundos.

Este artigo foi escrito pela equipe ZANTeam (@zan_team) & AntChain OpenLabs (@AntChainOpenLab), com a colaboração de Cara (@Cara6289).

ETH-6.02%
Ver original
Esta página pode conter conteúdos de terceiros, que são fornecidos apenas para fins informativos (sem representações/garantias) e não devem ser considerados como uma aprovação dos seus pontos de vista pela Gate, nem como aconselhamento financeiro ou profissional. Consulte a Declaração de exoneração de responsabilidade para obter mais informações.
  • Recompensa
  • Comentar
  • Republicar
  • Partilhar
Comentar
0/400
Nenhum comentário
  • Fixar
Negocie cripto em qualquer lugar e a qualquer hora
qrCode
Digitalizar para transferir a aplicação Gate
Novidades
Português (Portugal)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)