WEB3DEV

Cover image for Solidity: Brincando com Strings
Panegali
Panegali

Posted on

Solidity: Brincando com Strings

Iniciando com o Solidity

As strings de caracteres representam o coração de toda linguagem de programação porque, você sabe, os computadores geralmente interagem com humanos. Por esse motivo, o manuseio de strings é uma das primeiras funcionalidades desenvolvidas em qualquer linguagem. Além disso, o primeiro teste tradicionalmente imprime a string “Hello, world!”

Solidity não é uma exceção. Possui suporte nativo para strings, mas ainda assim, seu uso não é completo como em linguagens de alto nível como JavaScript, Python ou Java. Por exemplo, fora da caixa, o Solidity não oferece uma maneira nativa de comparar ou concatenar strings. No entanto, a documentação oferece uma solução válida para ambas as funções que dependem da abi.encodePacked()(falaremos sobre isso mais tarde) para comparar duas strings:

keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2)) 
Enter fullscreen mode Exit fullscreen mode

E para concatenar duas strings:

abi.encodePacked(s1, s2)
Enter fullscreen mode Exit fullscreen mode

Para entender melhor a mecânica interna dessas duas funções simples, como de costume, usaremos uma simples implementação de brinquedo:

pragma solidity ^0.7.1;

contract C {
    function compare(string memory s1, string memory s2) public pure returns (bool) {
        return keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2));
    }

    function concatenate(string memory s1, string memory s2) public pure returns (string memory) {
        return string(abi.encodePacked(s1, s2));
    }
}
Enter fullscreen mode Exit fullscreen mode

Como de costume, você pode brincar confortavelmente com ela usando o Remix. Uma vez compilado, você será capaz de invocar os dois métodos diretamente da interface:

A interface para invocar os métodos.

Chamar os dois métodos assinará uma transação contendo uma invocação para o método que passa os argumentos. A saída da transação é exibida nas janelas do console após a execução da concatenação da string (para exibir totalmente os resultados, lembre-se de clicar na pequena seta à direita):

Execução do método 'concatenar'.

No centro dessas duas implementações simples está a função abi.encodePacked(), que realiza um empacotamento compacto das variáveis ​​passadas como argumentos. Na figura a seguir (retirada da documentação), você pode ver como os bits de cada um dos argumentos são simplesmente concatenados na saída:

Um exemplo de como os argumentos passados ​​para encodePacked são realmente compactados.

Um ponto interessante nessa codificação é que ela é inerentemente ambígua, então não há como decodificá-la. No código a seguir, simplesmente testamos essa ambiguidade comparando a codificação de dois conjuntos de strings diferentes. Com o empacotamento no local, as duas invocações retornarão a sequência exata de bytes porque ambas as invocações retornarão a string "aab" sem considerar o comprimento diferente das strings de entrada:

pragma solidity ^0.7.1;

contract ambiguity {
    function test_ambiguity() public pure returns (bool) {
        return (keccak256(abi.encodePacked("aa", "b")) == keccak256(abi.encodePacked("a", "ab")));
    }
}
Enter fullscreen mode Exit fullscreen mode

Comparar os resultados da codificação usando keccak256()é uma abordagem comum no Solidity por causa de sua eficiência de gás.

Conclusão

A manipulação básica de strings é oferecida pelo Solidity não de forma nativa, mas por meio de um uso bastante padronizado de algum elemento nativo e eficiente.

Existem bibliotecas de manipulação de strings mais sofisticadas disponíveis. Existe até uma biblioteca de analisador JSON.

Meu conselho pessoal é manter esse tipo de manipulação o mais baixo possível. Mensagens para o usuário, manipulação JSON complexa etc. devem ser mantidas longe da blockchain. A blockchain deve ser considerada um back-end especializado, cujas performances dependem da representação de cada uma das variáveis ​​envolvidas.

Referências (em inglês)

  1. Documentação do Solidity 7.1.
  2. Biblioteca de utilitários de String e Slice para Solidity.
  3. Utilitários Padrão do Solidity.

Artigo escrito por Rosario De Chiara e traduzido por Marcelo Panegali

Top comments (0)