📌

[Astar]コントラクト備忘録50(他のコントラクトから値の取得やトランザクションの実行をしてみよう)

2023/03/21に公開

本日は、コントラクトから他のコントラクトの値の取得、トランザクションの実行を行っていきたいと思います。

なお、こちらの記事はRealtakahashiさんの下の記事
https://theastarbulletin.news/how-to-implement-a-cross-call-contract-with-ink-93976b6f589

の「Cross call contract」を理解するための準備用として作成しました。

では、見てみましょう。

まず、今回作成したいのは、下のような状態です。

これを実現するには、以下の4つのステップを踏む必要があります。

1 pub use

まずは、参照されるコントラクトを他からアクセス可能にします。

下のように、pub useを用いています。

これにより、「Flipper4Ref」を他から参照できるようになりました。

2 Cargo.tomlの「dependencies」

次は、参照コントラクトを依存関係とするために、Cargo.tomlに次のように記載します。

3 use

次は、モジュール内で、「Flipper4Ref」を使用するために、下のように宣言します。

4 型の指定

最後に、「from_account_id」関数を使う際に、型として指定します。

lib.rs(flipper_3)
#![cfg_attr(not(feature = "std"), no_std)]

#[ink::contract]
mod flipper_3 {
    use flipper_4::Flipper4Ref;
    /// Defines the storage of your contract.
    /// Add new fields to the below struct in order
    /// to add new static storage fields to your contract.
    #[ink(storage)]
    pub struct Flipper3 {
        /// Stores a single `bool` value on the storage.
        value: bool
    }

    impl Flipper3 {
        /// Constructor that initializes the `bool` value to the given `init_value`.
        #[ink(constructor)]
        pub fn new(init_value: bool) -> Self {
            Self { 
                value: init_value,
            }
        }

        /// Constructor that initializes the `bool` value to `false`.
        ///
        /// Constructors can delegate to other constructors.
        #[ink(constructor)]
        pub fn default() -> Self {
            Self::new(Default::default())
        }

        /// A message that can be called on instantiated contracts.
        /// This one flips the value of the stored `bool` from `true`
        /// to `false` and vice versa.
        #[ink(message)]
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Simply returns the current value of our `bool`.
        #[ink(message)]
        pub fn get(&self) -> bool {
            self.value
        }

        #[ink(message)]
        pub fn other_contract_flip(&mut self, flipper:AccountId) {
            let mut interface: Flipper4Ref = ink::env::call::FromAccountId::from_account_id(flipper);
            interface.flip();
        }

        #[ink(message)]
        pub fn other_contract_get(&self, flipper:AccountId) -> bool {
            let interface: Flipper4Ref = ink::env::call::FromAccountId::from_account_id(flipper);
            interface.get()
        }

    }
}
cargo.toml(flipper_3)
[package]
name = "flipper_3"
version = "0.1.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"

[dependencies]
ink = { version = "4.0.0-rc", default-features = false }

scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.3", default-features = false, features = ["derive"], optional = true }
flipper_4 = { version = "0.1.0", path = "../flipper_4", default-features = false, features = ["ink-as-dependency"] }

[lib]
path = "lib.rs"
crate-type = ["cdylib","rlib"]

[features]
default = ["std"]
std = [
    "ink/std",
    "scale/std",
    "scale-info/std",
]
ink-as-dependency = []
lib.rs(flipper_4)
#![cfg_attr(not(feature = "std"), no_std)]

pub use self::flipper_4::{Flipper4, Flipper4Ref};

#[ink::contract]
mod flipper_4 {
    /// Defines the storage of your contract.
    /// Add new fields to the below struct in order
    /// to add new static storage fields to your contract.
    #[ink(storage)]
    pub struct Flipper4 {
        /// Stores a single `bool` value on the storage.
        value: bool
    }

    impl Flipper4 {
        /// Constructor that initializes the `bool` value to the given `init_value`.
        #[ink(constructor)]
        pub fn new(init_value: bool) -> Self {
            Self { 
                value: init_value,
            }
        }

        /// Constructor that initializes the `bool` value to `false`.
        ///
        /// Constructors can delegate to other constructors.
        #[ink(constructor)]
        pub fn default() -> Self {
            Self::new(Default::default())
        }

        /// A message that can be called on instantiated contracts.
        /// This one flips the value of the stored `bool` from `true`
        /// to `false` and vice versa.
        #[ink(message)]
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Simply returns the current value of our `bool`.
        #[ink(message)]
        pub fn get(&self) -> bool {
            self.value
        }

    }
}
cargo.toml(flipper_4)
[package]
name = "flipper_4"
version = "0.1.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"

[dependencies]
ink = { version = "4.0.0-rc", default-features = false }

scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.3", default-features = false, features = ["derive"], optional = true }

[lib]
path = "lib.rs"
crate-type = ["cdylib","rlib"]

[features]
default = ["std"]
std = [
    "ink/std",
    "scale/std",
    "scale-info/std",
]
ink-as-dependency = []

Discussion