Skip to content

Commit

Permalink
Add Selector Docs (#172)
Browse files Browse the repository at this point in the history
* 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
HCastano and cmichi authored Feb 21, 2023
1 parent 34abc91 commit 5ac9c82
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/basics/metadata.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Metadata
hide_title: true
slug: /metadata
slug: /basics/metadata
---

<img src="/img/title/metadata.svg" className="titlePic" />
Expand Down
88 changes: 88 additions & 0 deletions docs/basics/selectors.md
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!

:::
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = {
"basics/reading-values",
"basics/mutating-values",
"basics/events",
"basics/selectors",
"basics/trait-definitions",
"basics/cross-contract-calling",
"basics/upgradeability",
Expand Down

0 comments on commit 5ac9c82

Please sign in to comment.