👨‍🔧Seletores

Seletores no ink! são uma forma independente de linguagem de identificar construtores e mensagens. Eles são strings hexadecimais de quatro bytes que se parecem com:0x633aa551.

Você pode encontrar o seletor de um construtor ou mensagem ink! nos metadados do seu contrato, procurando pelo campo "selector" do dispatchable de interesse.

Aqui está um exemplo de como você pode obter o nome da mensagem e o seletor dos metadados do seu contrato usando o jq.

cat target/ink/flipper.json | jq '.spec.messages[0] | "\(.label): \(.selector)"'
"flip: 0x633aa551"

Cálculo do Seletor.

Se você não tem acesso aos metadados de um contrato, também é possível calculá-lo por conta própria.

O algoritmo usado pelo ink! é bastante simples:

  1. Obtenha apenas o nome do construtor ou mensagem

  2. Calcule o hash BLAKE2 do nome

  3. Utilize os primeiros quatro bytes do hash como seletor

Vamos seguir um pequeno exemplo para ver como isso funciona na prática. Considere a seguinte mensagem:

#[ink(message)]
fn frobinate(&mut self, fro: bool, bi: u32, nate: AccountId) -> bool {
    unimplemented!()
}

Para calcular o seletor, nós:

  1. Obtemos o nome da mensagem, frobinate

  2. CalculamosBLAKE2("frobinate") = 0x8e39d7f22ef4f9f1404fe5200768179a8b4f2b67799082d7b39f6a8ca82da8f1

  3. Obtemos os primeiros quatro bytes, 0x8e39d7f2

Cálculo do Seletor: Traits do ink!

Essas regras mudam um pouco se você definir mensagens usando a macro [ink::trait_definition]. Para nosso primeiro passo, em vez de apenas pegar o nome da mensagem, agora também adicionamos o nome do trait ao cálculo do seletor.

cat target/ink/trait-flipper.json | jq '.spec.messages[0] | "\(.label): \(.selector)"'
"Flip::flip: 0xaa97cade"

Vamos ver como isso seria na prática. Considere o seguinte trait:

#[ink::trait_definition]
pub trait Frobinate {
    fn frobinate(&mut self, fro: bool, bi: u32, nate: AccountId) -> bool;
}

-- snip --

impl Frobinate for Contract {
    #[ink(message)]
    fn frobinate(&mut self, fro: bool, bi: u32, nate: AccountId) -> bool {
        unimplemented!()
    }
}

Para calcular o seletor, nós:

  1. Obtemos o nome do trait e o nome da mensagem, Frobinate::frobinate

  2. Calculamos BLAKE2("Frobinate::frobinate") = 0x8915412ad772b2a116917cf75df4ba461b5808556a73f729bce582fb79200c5b

  3. Obtemos os primeiros quatro bytes, 0x8915412a

Dica: Não se preocupe se você não conseguir calcular manualmente o hash BLAKE2 de uma string. Você pode usar as ferramentas Substrate de Shawn para fazer isso por você!

Last updated

Was this helpful?