Similar a abi.encode, mas codifica os argumentos de uma maneira mais compacta, sem preenchimento, o que pode ser útil para certas operações criptográficas. No entanto, a falta de preenchimento pode levar a ambiguidades em certas situações, portanto, deve ser usado com cautela.
Uso: Codifica os argumentos fornecidos com um seletor de função específico. Útil para chamadas de funções em contratos externos quando o seletor da função é conhecido.
O seletor de função é essencialmente a assinatura da função codificada em 4 bytes. Essa funcionalidade é particularmente útil ao fazer chamadas de baixo nível ou ao interagir com contratos cujas interfaces podem não estar totalmente definidas no momento da compilação.
Vamos incluir um exemplo de como usar abi.encodeWithSelector em Solidity para preparar dados para uma chamada de contrato de baixo nível:
// SPDX-License-Identifier: MITpragmasolidity^0.8.0;contract Receiver{eventReceived(uint256indexedvalue, addresssender);// Uma função simples que emite um evento com o valor e o remetentefunctionreceiveValue(uint256value)public{emitReceived(value,msg.sender);}}contract Caller{// Função que chama `receiveValue` no contrato Receiver usando abi.encodeWithSelectorfunctioncallReceiveValue(address_receiver,uint256_value)public{// Primeiro, calculamos o seletor da função.// A assinatura da função é "receiveValue(uint256)"bytes4 selector =bytes4(keccak256("receiveValue(uint256)"));// Em seguida, codificamos o seletor junto com os argumentos da função.bytesmemory data =abi.encodeWithSelector(selector, _value);// Realizamos a chamada de baixo nível.(bool success,)= _receiver.call(data);require(success,"A chamada falhou.");}}
Neste exemplo:
Receiver: É um contrato que possui uma função receiveValue, que emite um evento quando chamada. Essa função pode conter qualquer lógica que você deseja invocar em outro contrato.
Caller: É um contrato que realiza uma chamada ao contrato Receiver. Ele usa abi.encodeWithSelector para preparar os dados da chamada. Isso inclui o seletor da função, que identifica qual função chamar no contrato Receiver, e os argumentos para essa função.
bytes4 selector = bytes4(keccak256("receiveValue(uint256)")); calcula o seletor da função com base na sua assinatura. A assinatura é simplesmente o nome da função seguido dos tipos de seus parâmetros entre parênteses, codificado em 4 bytes.
abi.encodeWithSelector(selector, _value) codifica esses dados em um formato que o contrato Receiver pode decodificar e executar.
Similar a abi.encodeWithSelector, mas em vez de fornecer o seletor de função como um valor bytes4, a assinatura da função é fornecida como uma string. O Solidity calcula o seletor de função correspondente.
Exemplo:
Neste exemplo, functionName(uint256,address) é a assinatura da função.
Decodifica os dados codificados de acordo com as regras ABI nos tipos especificados. É útil para interpretar os dados de saída de chamadas de funções de baixo nível ou respostas de chamadas a outros contratos.