Skip to content

Commit 3cc2e71

Browse files
cmichiascjones
andauthored
Add more content to architecture file (use-ink#1370)
* Fix some text * Add more content to `ARCHITECTURE.md` * Update ARCHITECTURE.md Co-authored-by: Andrew Jones <ascjones@gmail.com> Co-authored-by: Andrew Jones <ascjones@gmail.com>
1 parent d73fa82 commit 3cc2e71

File tree

4 files changed

+88
-14
lines changed

4 files changed

+88
-14
lines changed

.images/pallet-contracts.png

313 KB
Loading

ARCHITECTURE.md

+85-11
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,35 @@ You can find the crate documentation on docs.rs or for our
1515
ink! is composed of a number of crates that are all found in the
1616
`crates/` folder. On a high-level those can be grouped as:
1717

18-
* `lang`: The ink! language itself.
19-
* `allocator`: The allocator used for dynamic memory allocation in a contract.
20-
* `engine`: An off-chain testing engine, it simulates a blockchain
21-
environment and allows mocking specified conditions.
22-
* `env`: Serves two roles:
18+
* [`lang`](https://github.com/paritytech/ink/tree/master/crates/lang):
19+
The ink! language itself.
20+
* [`allocator`](https://github.com/paritytech/ink/tree/master/crates/allocator):
21+
The allocator used for dynamic memory allocation in a contract.
22+
* [`engine`](https://github.com/paritytech/ink/tree/master/crates/engine):
23+
An off-chain testing engine, it simulates a blockchain environment and allows
24+
mocking specified conditions.
25+
* [`env`](https://github.com/paritytech/ink/tree/master/crates/env):
26+
Serves two roles:
2327
* Exposes environmental functions, like information about the caller
2428
of a contract call, getting random entropy, or e.g. self-terminating the
2529
contract.
2630
* Provides the connection to the [`pallet-contracts`](https://github.com/paritytech/substrate/tree/master/frame/contracts),
2731
so anything that calls into the underlying execution engine of the smart contract.
2832
This includes getting and setting a smart contracts storage, as well
2933
as the mentioned environmental functions.
30-
* `metadata`: Describes the contract in a platform agnostic way, i.e.
31-
its interface and the types, its storage layout, etc.
32-
* `prelude`: Provides an interface to typical standard library types and
34+
* [`metadata`](https://github.com/paritytech/ink/tree/master/crates/metadata):
35+
Describes the contract in a platform agnostic way, i.e. its interface
36+
and the types, its storage layout, etc.
37+
* [`prelude`](https://github.com/paritytech/ink/tree/master/crates/prelude):
38+
Provides an interface to typical standard library types and
3339
functionality (like `vec` or `string`). Since contracts are run in a
3440
`no_std` environment we provide this crate as an entrypoint for accessing
3541
functionality of the standard library.
36-
* `primitives`: Utilities that are used internally by multiple ink! crates.
37-
* `storage`: The collections that are available for contract developers
38-
to put in a smart contracts storage.
42+
* [`primitives`](https://github.com/paritytech/ink/tree/master/crates/primitives):
43+
Utilities that are used internally by multiple ink! crates.
44+
* [`storage`](https://github.com/paritytech/ink/tree/master/crates/prelude):
45+
The collections that are available for contract developers to put in
46+
a smart contracts storage.
3947

4048
An important thing to note is that the crates are primarily run in
4149
a `no_std` environment.
@@ -96,3 +104,69 @@ At the moment we're still stuck with one nightly feature though:
96104
[alloc_error_handler](https://github.com/rust-lang/rust/issues/51540).
97105
It's needed because we use a specialized memory allocation handler,
98106
the `ink_allocator` crate.
107+
108+
## Interaction with `pallet-contracts`
109+
110+
The Wasm blob to which an ink! contract is compiled is executed in
111+
an execution environment named [`pallet-contracts`](https://github.com/paritytech/substrate/commits/master/frame/contracts)
112+
on-chain.
113+
This `pallet-contracts` is the smart contracts module of
114+
[the Substrate blockchain framework](http://substrate.io/).
115+
116+
The relationship is as depicted in this diagram:
117+
118+
<img src="./.images/pallet-contracts.png" alt="pallet-contracts Interaction" width="800" />
119+
120+
### Communication with the pallet
121+
ink! uses a static buffer for interacting with `pallet-contracts`, i.e.
122+
to move data between the pallet and a smart contract.
123+
The advantage of a static buffer is that no gas-expensive heap allocations
124+
are necessary, all allocations are done using simple pointer arithmetic.
125+
The implementation of this static buffer is found in
126+
[`ink_env/src/engine/on_chain/buffer.rs`](https://github.com/paritytech/ink/blob/master/crates/env/src/engine/on_chain/buffer.rs).
127+
128+
The methods for communicating with the pallet are found in [`ink_env/src/engine/on_chain/impls.rs`](https://github.com/paritytech/ink/blob/master/crates/env/src/engine/on_chain/impls.rs).
129+
If you look at the implementations you'll see a common pattern of
130+
131+
* SCALE-encoding values on the ink! side in order to pass them as a slice
132+
of bytes to the `pallet-contracts`.
133+
* SCALE-decoding values that come from the `pallet-contracts` side in order
134+
to convert them into the proper types on the ink! side, making them available
135+
for contract developers.
136+
137+
### The pallet API
138+
The function signature of the `pallet-contracts` API functions is defined in
139+
[`ink_env/src/engine/on_chain/ext.rs`](https://github.com/paritytech/ink/blob/master/crates/env/src/engine/on_chain/ext.rs).
140+
You'll see that we import different versions of API functions, something
141+
like the following excerpt:
142+
143+
```rust
144+
#[link(wasm_import_module = "seal0")]
145+
extern "C" {
146+
pub fn seal_get_storage(
147+
key_ptr: Ptr32<[u8]>,
148+
output_ptr: Ptr32Mut<[u8]>,
149+
output_len_ptr: Ptr32Mut<u32>,
150+
) -> ReturnCode;
151+
}
152+
153+
#[link(wasm_import_module = "seal1")]
154+
extern "C" {
155+
pub fn seal_set_storage(
156+
key_ptr: Ptr32<[u8]>,
157+
value_ptr: Ptr32<[u8]>,
158+
value_len: u32,
159+
) -> ReturnCode;
160+
}
161+
```
162+
163+
Smart contracts are immutable, thus the `pallet-contracts` can never change or remove
164+
old API functions ‒ otherwise smart contracts that are deployed on-chain would break.
165+
166+
Hence there is this version mechanism. Functions start out at version `seal0` and for
167+
each new released iteration of the function there is a new version of it introduced.
168+
In the example above you can see that we changed the function `seal_set_storage` at
169+
one point.
170+
171+
The prefix `seal` here is for historic reasons. There is some analogy to sealing a
172+
contract. And we found seals to be a cute animal as well ‒ like squids!

crates/env/src/topics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
//! Docs
15+
//! This module contains the implementation for the event topic logic.
1616
1717
use crate::Environment;
1818

crates/lang/ir/src/ir/ink_test.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ impl TryFrom<syn::ItemFn> for InkTest {
3131
}
3232

3333
impl InkTest {
34-
/// Returns `Ok` if the trait matches all requirements for an ink! trait definition.
34+
/// Returns `Ok` if the test matches all requirements for an ink! test definition.
3535
pub fn new(attr: TokenStream2, input: TokenStream2) -> Result<Self, syn::Error> {
3636
if !attr.is_empty() {
3737
return Err(format_err_spanned!(
3838
attr,
39-
"unexpected attribute input for ink! trait definition"
39+
"unexpected attribute input for ink! test definition"
4040
))
4141
}
4242
let item_fn = syn::parse2::<syn::ItemFn>(input)?;

0 commit comments

Comments
 (0)