O modelo contém código estruturado que fornece um ponto de partida para escrever um contrato ink!. A seguir, daremos uma olhada no que os arquivos contêm. Os arquivos que você obtém localmente serão semelhantes, apenas adicionamos comentários explicativos aqui.
[package]name ="foobar"version ="0.1.0"authors = ["[your_name] <[your_email]>"]edition ="2021"[dependencies]# The `ink` crate contains the ink! eDSL and re-exports# a number of other ink! specific crates.For example,# `ink::env` is the `ink_env` crate that contains functions# to interact with a contract's environment (querying information# about a caller, the current block number, etc.).ink = { version ="4.0.0-beta", default-features =false }# Substrate blockchains use the SCALE codec for anything to# do with data encoding/decoding.If an ink! contract is called# the passed values have to be SCALE-encoded and return values# have to be SCALE-decoded.All values that are put into a# contract's storage are SCALE-encoded as well.scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }# Thiscrate is used to write information about a contract's# types into the contract's metadata (i.e. its ABI).This is# needed so that a client knows that a contract message requires# e.g. an Array and that it has to SCALE-encode the value as an Array.scale-info = { version = "2.3", default-features = false, features = ["derive"], optional = true }[dev-dependencies]# This developer dependency is for the End-to-End testing framework.ink_e2e = { path = "../../crates/e2e" }[lib]name = "foobar"path = "lib.rs"# This setting typically specifies that you'd like the compiler to# create a dynamic system library.ForWebAssembly though it specifies# that the compiler should create a `*.wasm` without a start function.crate-type= [ "cdylib",][features]default = ["std"]std = [ "ink/std", "scale/std", "scale-info/std",]ink-as-dependency = []# This feature is just a convention, so that the end-to-end tests# are only executed if `cargo test` is explicitly invoked with# `--features e2e-tests`.e2e-tests = []
O código estruturado será semelhante ao seguinte, embora tenhamos alterado os comentários para explicar o que está acontecendo em alto nível.
// If the `std` feature from the `Cargo.toml` is not enabled// we switch on `no_std`, this has the effect of Rusts standard// library not being included in our contract.//// The Rust standard library is OS-dependent and Wasm is// architecture independent.#![cfg_attr(not(feature ="std"), no_std)]// This is the ink! macro, the starting point for your contract.// Everything below it might look like Rust code, but it is actually// run through a parser in ink!.#[ink::contract]pubmod flipper {/// This is the contract's storage. #[ink(storage)]pubstructFlipper { value:bool, }implFlipper {/// A constructor that the contract can be initialized with. #[ink(constructor)]pubfnnew(init_value:bool) -> Self {/* --snip-- */ }/// An alternative constructor that the contract can be/// initialized with. #[ink(constructor)]pubfnnew_default() -> Self {/* --snip-- */ }/// A state-mutating function that the contract exposes to the/// outside world.////// By default functions are private, they have to be annotated/// with `#[ink(message)]` and `pub` to be available from the/// outside. #[ink(message)]pubfnflip(&mut self) {/* --snip-- */ }/// A public contract function that has no side-effects.////// Note that while purely reading functions can be invoked/// by submitting a transaction on-chain, this is usually/// not done as they have no side-effects and the transaction/// costs would be wasted./// Instead those functions are typically invoked via RPC to/// return a contract's state. #[ink(message)]pubfnget(&self) ->bool {/* --snip-- */ } } #[cfg(test)]mod tests {use super::*;/// This attribute denotes that the test is executed in/// a simulated, mocked blockchain environment. There are/// functions available to influence how the test environment/// is configured (e.g. setting an account to a specified balance). #[ink::test]fndefault_works() {/* --snip-- */ }/* --snip-- */ } #[cfg(all(test, feature ="e2e-tests"))]mod e2e_tests {use super::*;use ink_e2e::build_message;typeE2EResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;/// With this attribute the contract will be compiled and deployed/// to a Substrate node that is required to be running in the/// background.////// We offer API functions that enable developers to then interact/// with the contract. ink! will take care of putting contract calls/// into transactions that will be submitted to the Substrate chain.////// Developers can define assertions on the outcome of their transactions,/// such as checking for state mutations, transaction failures or/// incurred gas costs. #[ink_e2e::test]asyncfnit_works(mut client: ink_e2e::Client<C, E>) ->E2EResult<()> {/* --snip-- */ }/* --snip-- */ }}