@@ -15,27 +15,35 @@ You can find the crate documentation on docs.rs or for our
15
15
ink! is composed of a number of crates that are all found in the
16
16
` crates/ ` folder. On a high-level those can be grouped as:
17
17
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:
23
27
* Exposes environmental functions, like information about the caller
24
28
of a contract call, getting random entropy, or e.g. self-terminating the
25
29
contract.
26
30
* Provides the connection to the [ ` pallet-contracts ` ] ( https://github.com/paritytech/substrate/tree/master/frame/contracts ) ,
27
31
so anything that calls into the underlying execution engine of the smart contract.
28
32
This includes getting and setting a smart contracts storage, as well
29
33
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
33
39
functionality (like ` vec ` or ` string ` ). Since contracts are run in a
34
40
` no_std ` environment we provide this crate as an entrypoint for accessing
35
41
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.
39
47
40
48
An important thing to note is that the crates are primarily run in
41
49
a ` no_std ` environment.
@@ -96,3 +104,69 @@ At the moment we're still stuck with one nightly feature though:
96
104
[ alloc_error_handler] ( https://github.com/rust-lang/rust/issues/51540 ) .
97
105
It's needed because we use a specialized memory allocation handler,
98
106
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!
0 commit comments