-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Write up selector docs * Move selector docs to own page * Add new selector page to Git * Update the Metadata page slug It seems like this section was moved and we forgot to update the slug * Apply suggestions from code review * Apply suggestions from code review --------- Co-authored-by: Michael Müller <[email protected]>
- Loading branch information
Showing
3 changed files
with
90 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
--- | ||
title: Selectors | ||
hide_title: true | ||
slug: /basics/selectors | ||
--- | ||
|
||
# Selectors | ||
|
||
Selectors in ink! are a language agnostic way of identifying constructors and messages. | ||
They are four-byte hexadecimal strings which look something like: `0x633aa551`. | ||
|
||
You can find the selector of an ink! constructor or message in your | ||
[contract metadata](/basics/metadata) by looking for the `selector` field of the dispatchable | ||
you're interested in. | ||
|
||
Here is an example of how you can grab the message name and selector from your contract | ||
metadata using [`jq`](https://stedolan.github.io/jq/). | ||
|
||
``` | ||
cat target/ink/flipper.json | jq '.spec.messages[0] | "\(.label): \(.selector)"' | ||
"flip: 0x633aa551" | ||
``` | ||
|
||
## Selector Calculation | ||
|
||
If you do not have access to a contract's metadata, you can also calculate it yourself. | ||
|
||
The algorithm ink! uses is fairly straightforward: | ||
1. Get _just_ the name of the constructor or message | ||
2. Compute the `BLAKE2` hash of the name | ||
3. Take the first four bytes of the hash as the selector | ||
|
||
Let's walk through a short example of what this looks like in practice. Consider the | ||
following message: | ||
|
||
```rust | ||
#[ink(message)] | ||
fn frobinate(&mut self, fro: bool, bi: u32, nate: AccountId) -> bool { | ||
unimplemented!() | ||
} | ||
``` | ||
|
||
To calculate the selector we: | ||
1. Grab the name of the message, `frobinate` | ||
2. Compute `BLAKE2("frobinate") = 0x8e39d7f22ef4f9f1404fe5200768179a8b4f2b67799082d7b39f6a8ca82da8f1` | ||
3. Grab the first four bytes, `0x8e39d7f2` | ||
|
||
## Selector Calculation: ink! Traits | ||
|
||
These rules change a bit if you define any messages using the `[ink::trait_defintion]` | ||
[macro](/basics/trait-definitions). For our first step, instead of taking _just_ the | ||
message name, we now also add the _trait name_ to the selector calculation. | ||
|
||
``` | ||
cat target/ink/trait-flipper.json | jq '.spec.messages[0] | "\(.label): \(.selector)"' | ||
"Flip::flip: 0xaa97cade" | ||
``` | ||
|
||
Let's see what this would look like in practice. Consider the following trait: | ||
|
||
```rust | ||
#[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!() | ||
} | ||
} | ||
``` | ||
|
||
To calculate the selector we: | ||
1. Grab the name of the trait **and** the name of the message, `Frobinate::frobinate` | ||
2. Compute `BLAKE2("Frobinate::frobinate") = 0x8915412ad772b2a116917cf75df4ba461b5808556a73f729bce582fb79200c5b` | ||
3. Grab the first four bytes, `0x8915412a` | ||
|
||
:::tip | ||
|
||
Don't worry if you're not able to calculate the `BLAKE2` hash of a string by hand. You | ||
can use [Shawn's Substrate Utilities](https://www.shawntabrizi.com/substrate-js-utilities/) | ||
to do it for you! | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters