Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch use.ink to 5.0 content by default #332

Merged
merged 20 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ node_modules/
babel.config.js
docusaurus.config.js
sidebars.js
versioned_docs/version-5.x/third-party-tools/swanky/Figure.tsx
versioned_docs/version-5.x/testing/testnet/Faucet.tsx
versioned_docs/version-4.x/third-party-tools/swanky/Figure.tsx
versioned_docs/version-4.x/testnet/Faucet.tsx
docs/third-party-tools/swanky/Figure.tsx
docs/testnet/Faucet.tsx
14 changes: 8 additions & 6 deletions docs/basics/cross-contract-calling.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ Data Ok(true)

## Builders
The
[`CreateBuilder`](https://docs.rs/ink_env/latest/ink_env/call/struct.CreateBuilder.html)
[`CreateBuilder`](https://docs.rs/ink_env/5.0.0/ink_env/call/struct.CreateBuilder.html)
and
[`CallBuilder`](https://docs.rs/ink_env/latest/ink_env/call/struct.CallBuilder.html)
[`CallBuilder`](https://docs.rs/ink_env/5.0.0/ink_env/call/struct.CallBuilder.html)
offer low-level, flexible interfaces for performing cross-contract calls. The
`CreateBuilder` allows you to instantiate already uploaded contracts, and the
`CallBuilder` allows you to call messages on instantiated contracts.
Expand Down Expand Up @@ -228,6 +228,7 @@ Below is an example of how to instantiate a contract using the `CreateBuilder`.
```rust
use contract::MyContractRef;
let my_contract: MyContractRef = build_create::<MyContractRef>()
.instantiate_v1()
.code_hash(Hash::from([0x42; 32]))
.gas_limit(0)
.endowment(10)
Expand Down Expand Up @@ -272,6 +273,7 @@ Below is an example of how to call a contract using the `CallBuilder`. We will:
```rust
let my_return_value = build_call::<DefaultEnvironment>()
.call(AccountId::from([0x42; 32]))
.call_v1()
.gas_limit(0)
.transferred_value(10)
.exec_input(
Expand Down Expand Up @@ -333,11 +335,11 @@ These allow contract developers to handle two types of errors:
2. Error from the programming language (e.g `LangError`s)

See the documentation for
[`try_instantiate`](https://docs.rs/ink_env/latest/ink_env/call/struct.CreateBuilder.html#method.try_instantiate),
[`try_invoke`](https://docs.rs/ink_env/latest/ink_env/call/struct.CallBuilder.html#method.try_invoke-2),
[`ink::env::Error`](https://docs.rs/ink_env/latest/ink_env/enum.Error.html)
[`try_instantiate`](https://docs.rs/ink_env/5.0.0/ink_env/call/struct.CreateBuilder.html#method.try_instantiate),
[`try_invoke`](https://docs.rs/ink_env/5.0.0/ink_env/call/struct.CallBuilder.html#method.try_invoke-2),
[`ink::env::Error`](https://docs.rs/ink_env/5.0.0/ink_env/enum.Error.html)
and
[`ink::LangError`](https://docs.rs/ink/latest/ink/enum.LangError.html)
[`ink::LangError`](https://docs.rs/ink/5.0.0/ink/enum.LangError.html)
for more details on proper error handling.

:::tip
Expand Down
22 changes: 13 additions & 9 deletions docs/basics/env-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ title: Environment Functions
slug: /basics/environment-functions
---

<img src="/img/title/env-function.svg" className="titlePic" />

# Environment Functions

ink! exposes a number of handy environment functions.
A full overview [is found here](https://docs.rs/ink_env/4.0.0/ink_env/#functions).
A full overview [is found here](https://docs.rs/ink_env/5.0.0/ink_env/#functions).

In an `#[ink(constructor)]` use `Self::env()` to access those,
in an `#[ink(message)]` use `self.env()`.
So e.g. `Self::env().caller()` or `self.env().caller()`.

Some handy functions include:

* [`caller()`](https://docs.rs/ink_env/4.0.0/ink_env/fn.caller.html): Returns the address of the caller of the executed contract.
* [`account_id()`](https://docs.rs/ink_env/4.0.0/ink_env/fn.account_id.html): Returns the account ID of the executed contract.
* [`balance()`](https://docs.rs/ink_env/4.0.0/ink_env/fn.balance.html): Returns the balance of the executed contract.
* [`block_number()`](https://docs.rs/ink_env/4.0.0/ink_env/fn.block_number.html): Returns the current block number.
* [`emit_event(…)`](https://docs.rs/ink_env/4.0.0/ink_env/fn.emit_event.html): Emits an event with the given event data.
* [`transfer(…)`](https://docs.rs/ink_env/4.0.0/ink_env/fn.transfer.html): Transfers value from the contract to the destination account ID.
* [`hash_bytes(…)`](https://docs.rs/ink_env/4.0.0/ink_env/fn.hash_bytes.html): Conducts the crypto hash of the given input and stores the result in output.
* […and many more](https://docs.rs/ink_env/4.0.0/ink_env/#functions).
* [`caller()`](https://docs.rs/ink_env/5.0.0/ink_env/fn.caller.html): Returns the address of the caller of the executed contract.
* [`account_id()`](https://docs.rs/ink_env/5.0.0/ink_env/fn.account_id.html): Returns the account ID of the executed contract.
* [`balance()`](https://docs.rs/ink_env/5.0.0/ink_env/fn.balance.html): Returns the balance of the executed contract.
* [`block_number()`](https://docs.rs/ink_env/5.0.0/ink_env/fn.block_number.html): Returns the current block number.
* [`emit_event(…)`](https://docs.rs/ink_env/5.0.0/ink_env/fn.emit_event.html): Emits an event with the given event data.
* [`transfer(…)`](https://docs.rs/ink_env/5.0.0/ink_env/fn.transfer.html): Transfers value from the contract to the destination account ID.
* [`hash_bytes(…)`](https://docs.rs/ink_env/5.0.0/ink_env/fn.hash_bytes.html): Conducts the crypto hash of the given input and stores the result in output.
* […and many more](https://docs.rs/ink_env/5.0.0/ink_env/#functions).
128 changes: 116 additions & 12 deletions docs/basics/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,32 +62,127 @@ for an elaborate example which uses events.

## Event Definition

Since ink! version 5.0, events can be defined independently of the contract which emits them.
Events can now be defined once and shared across multiple contracts.

This is useful for events for contracts which conform to standards such as ERC-20:
contract indexers/explorers are now able to group all e.g. `Transferred` events.

This is how an event definition looks:

```rust
#[ink(event)]
use ink::primitives::AccountId;

#[ink::event]
pub struct Transferred {
#[ink(topic)]
from: Option<AccountId>,

#[ink(topic)]
to: Option<AccountId>,
amount: u128,
}
```
> Note that generics are [not currently supported](https://github.com/paritytech/ink/issues/2044)
> , so the concrete types of `Environment`
> specific types such as `AccountId` must match up with the types used in the contract.

amount: Balance
This definition can exist within a contract definition module (inline events), in a different
module in the same crate or even in a different crate to be shared by multiple contracts.

}
### Legacy syntax for inline Event definitions

Events defined within a `#[ink::contract]` module can continue to use the original syntax for an
event definition, using the `#[ink(event)]` attribute. Under the covers this is simply expanded
to the new top level `#[ink::event]` macro, so both events defined using the legacy style and
using the new `event` attribute macro directly will behave exactly the same.

### Topics

When an event is emitted, 0 or more topics can be associated with it. The event is then indexed
together with other events with the same topic value.

An event's fields can be annotated with `#[ink(topic)]` (see example), which will result in a
topic derived from the value of that field being emitted together with the event.

Topics are by default a 32 byte array (`[u8; 32]`), although this is configurable on the
Polkadot SDK runtime level. If the SCALE encoded bytes of a field value are `<= 32`, then the
encoded bytes are used directly as the topic value.

For example, in the common case of indexing a field of type `AccountId`, where the default
`AccountId` type is 32 bytes in length, the topic value will be the encoded account id itself. This
makes it easy to filter for all events which have a topic of a specific `AccountId`.

If however the size of the encoded bytes of the value of a field exceeds 32, then the encoded
bytes will be hashed using the `Blake2x256` hasher.

> Topics are a native concept in the Polkadot SDK, and can be queried via [`EventTopics`](https://docs.rs/frame-system/latest/frame_system/pallet/storage_types/struct.EventTopics.html)

How to choose which fields to make topics? A good rule of thumb is to ask yourself if somebody
might want to search for this topic. For this reason the `amount` in the example `Transferred` event
above was not made indexable ‒ there will most probably be a lot of different events with differing
amounts each.

#### Signature Topic

By default all events have a signature topic. This allows indexing of all events of the same
type, emitted by different contracts. The `#[ink::event]` macro generates a signature topic at
compile time by hashing the name of the event concatenated with the *names of the types* of the all
the field
names:
```
blake2b("Event(field1_type,field2_type)")`
```
So for our `Transferred` example it will be:
```
blake2b("Transferred(Option<AccountId>,Option<AccountId>,u128)")`
```

:::caution
Important caveat: because the *name* of the field type is used, refactoring an event
definition to use a type alias or a fully qualified type will change the signature topic, even
though the underlying type is the same. Two otherwise identical definitions of an event with the
same name and same field types but different field type names will have different signature
topics.
:::

When decoding events emitted from a contract, signature topics are now required to determine which
type of event to decode into.

Add the `#[ink(topic)]` attribute tag to each item in your event that you want to have indexed.
A good rule of thumb is to ask yourself if somebody might want to search for this topic.
For this reason the `amount` in the exemplary event above was not
made indexable ‒ there will most probably be a lot of different events with
differing amounts each.
#### Anonymous Events

The signature of the event is by default one of the topics of the event, except
if you annotate the event with `#[ink(anonymous)]`.
See [here](../macros-attributes/anonymous.md) for details on this attribute.
Events annotated with `anonymous` will not have a signature topic generated and published with the
event.

For inline events, this can be done by marking the event with the `anonymous` attribute e.g.

```rust
#[ink(event, anonymous)]
pub struct Event { .. }
```
or
```rust
#[ink(event)]
#[ink(anonymous)]
pub struct Event { .. }
```

For events defined using the `#[ink::event]` macro, the `anonymous` flag needs to be added as an
argument:

```rust
#[ink::event(anonymous)]
pub struct Event { .. }
```

Without a signature topic, indexers will not be able to index over the type of the event, which
may be desirable for some contracts, and would be a small gas cost optimization if necessary.

However, when interacting with the contract from a client, no signature topic means that another
way is required to determine the type of the event to be decoded into (i.e. how do we know it is
a `Transferred` event, not an `Approval` event. One way would be to try decoding for each type
of event defined in the metadata of the contract until one succeeds. If calling a specific
`message`, it may be known up front what type of event that message will raise, so the client
code could just decode into that event directly.

## Emitting Events in a Constructor

Expand Down Expand Up @@ -128,3 +223,12 @@ pub fn transfer(&mut self, to: AccountId, amount: Balance) -> Result {
Ok(())
}
```

## Cost of using Events

When using events and topics, developers should be mindful of the costs associated. Firstly: if
optimizing for contract size, using events will increase the size of the final code size. So
minimizing or eliminating event usage where necessary will reduce contract size. The same can be
said for the execution (aka gas) costs when using events. We recommend considering the cost of
events when using them, and measuring the code size and gas costs with different usage patterns
when optimizing.
File renamed without changes.
6 changes: 3 additions & 3 deletions docs/basics/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,12 @@ The contract `spec` consists of the following **required** keys:
- `return_type`: The return type of the message.
- `docs`: The message documentation.
- `environment`: Configuration of the types that the host blockchain operates with.
You can check default types in [Environment](https://use.ink/basics/chain-environment-types) section.
You can check default types in [Environment](./environment.md) section.
- `accountId`: The type describing an account address.
- `balance`: The type describing balance values.
- `blockNumber`: The type describing a block number.
- `chainExtension`: The type describing the chain extension for the environment.
For more information about usage and definition check [this section](https://use.ink/macros-attributes/chain-extension).
For more information about usage and definition check [this section](../macros-attributes/chain-extension.md).
- `maxEventTopics`: The maximum number of supported event topics provided by the runtime.
- `timestamp`: the type describing a timestamp.
- `events`: The events of the contract.
Expand All @@ -203,7 +203,7 @@ comes from the smart contracting language itself, and not the contract nor the u
environment (e.g `pallet-contracts`).

All ink! messages and constructors now return a `Result` which uses this as the `Error`
variant (see the [`LangError`](https://docs.rs/ink/4.0.0/ink/enum.LangError.html) docs for more).
variant (see the [`LangError`](https://docs.rs/ink/5.0.0/ink/enum.LangError.html) docs for more).

:::

Expand Down
2 changes: 2 additions & 0 deletions docs/basics/selectors.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ hide_title: true
slug: /basics/selectors
---

<img src="/img/title/selector-hex.svg" className="titlePic" />

# Selectors

Selectors in ink! are a language agnostic way of identifying constructors and messages.
Expand Down
2 changes: 1 addition & 1 deletion docs/basics/storing-values.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ they were primitive types.

### String, Vector and More

The [`ink_prelude`](https://docs.rs/ink_prelude/latest/ink_prelude/index.html) crate provides an efficient approach to import commonly used Rust types such as `String` and `Vec`, ensuring safe usage within an ink! contract.
The [`ink_prelude`](https://docs.rs/ink_prelude/5.0.0/ink_prelude/index.html) crate provides an efficient approach to import commonly used Rust types such as `String` and `Vec`, ensuring safe usage within an ink! contract.

This simplifies the type referencing process between the `std` and `no_std` environments. Typically, these types are defined within the `std` crate in the `std` environment, and the `alloc` crate in the `no_std` environment. Given that ink! smart contract code is compiled in both environments (`no_std` for production and `std` for unit tests), developers might find themselves writing intricate conditional compilation macros. The `ink_prelude` crate conveniently re-exports these types, eliminating this complexity.

Expand Down
2 changes: 1 addition & 1 deletion docs/basics/trait-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Marks trait definitions to ink! as special ink! trait definitions.

There are some restrictions that apply to ink! trait definitions that
this macro checks. Also ink! trait definitions are required to have specialized
structure so that the main [`#[ink::contract]`](https://docs.rs/ink/4.0.0/ink/attr.contract.html) macro can
structure so that the main [`#[ink::contract]`](https://docs.rs/ink/5.0.0/ink/attr.contract.html) macro can
properly generate code for its implementations.

# Example: Definition
Expand Down
25 changes: 25 additions & 0 deletions docs/basics/upgradeability.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,31 @@ As you can see, delegatee's code looks like a normal ink! Smart Contract with so
- `addresses` mapping key is identical
- Constructor does not have any logic, as the code is never instantiated. (It can be, but plays no effect on the execution)

### Delegate dependency locks

In a delegator contract pattern, one contract delegates calls to another contract.
Thus it depends upon the contract code to which it delegates. Since on-chain contract code
can be deleted by anybody if there are no instances of the contract on the chain, this would
break the `delegator` contract. To prevent this, the `delegator` contract can utilize the
`lock_delegate_dependency` and `unlock_delegate_dependency` host functions. Calling
`lock_delegate_dependency` will prevent the code at the given hash from being deleted e.g.

```rust
self.env().lock_delegate_dependency(&code_hash);
```

A subsequent call to `unlock_delegate_dependency` from within the `delegator` contract
instance releases the lock from that contract, allowing that code at the given hash to be
deleted if no other instances of the contract or delegate dependency locks exist.

```rust
self.env().lock_delegate_dependency(&code_hash);
```

Note that these two methods can be called by anybody executing the contract, so it is the
responsibility of the contract developer to ensure correct access control.
You can take a look at our [`upgradeable-contracts/delegator`](https://github.com/paritytech/ink-examples/tree/main/upgradeable-contracts#delegator)
example, which demonstrates the usage of these two functions.

## Note on the usage of wildcard selectors

Expand Down
12 changes: 6 additions & 6 deletions docs/basics/verification/contract-verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ process must recompile the contract in an identical host environment to
which it was originally built. The simplest way to do this is using a Docker
container.

Since ink! `4.0.0`, `cargo-contract` provides the necessary tools to produce
Since ink! 5.0, `cargo-contract` provides the necessary tools to produce
a verifiable build and verify a binary against the reference contract.

:::note
Contract verification tools are currently available in `cargo-contract`
version `4.0.0-alpha`. To install it, run
Contract verification tools are available from `cargo-contract`
version 4.0 on. To install it, run
```
cargo install cargo-contract --locked --version 4.0.0-alpha
cargo install cargo-contract --locked --version ^4
```
:::

Expand Down Expand Up @@ -117,5 +117,5 @@ of all contracts to be visible. Specify a relative manifest path to the root con
`cargo contract build --verifiable --manifest-path ink-project-a/Cargo.toml`
:::

You can find a Dockefile and further documentation on image usage
in [the `cargo-contract` repository](https://github.com/paritytech/cargo-contract/tree/master/build-image)
You can find a Dockerfile and further documentation on image usage
in [the `cargo-contract` repository](https://github.com/paritytech/cargo-contract/tree/master/build-image)
Loading
Loading