Search code examples
substraterust-ink

How do I call an existing contract from another contract in rust-ink?


I have two very basic rust-ink dapp contracts:

Dapp 1

#![cfg_attr(not(feature = "std"), no_std)]

use ink_lang as ink;
use dapp2;

#[ink::contract]
pub mod dapp1 {
    use dapp2::dapp2::Dapp2;

    #[ink(storage)]
    pub struct Dapp1 {
        dapp2_instance: Dapp2
    }

    impl Dapp1 {
        /// Get existing `Dapp2` contract at `address`
        #[ink(constructor)]
        pub fn new(address: AccountId) -> Self {
            let dapp2_instance: Dapp2 = ink_env::call::FromAccountId::from_account_id(address);
            Self {
                dapp2_instance
            }
        }

        /// Calls the Dapp2 contract.
        #[ink(message)]
        pub fn dapp2_do_something(&mut self) -> u8 {
            self.dapp2_instance.do_something()
        }
    }
}

Dapp 1 specifies dapp2 as a dependency in the toml:

dapp2 = { version = "3.0.0-rc7", path ="../dapp2", default-features = false, features = ["ink-as-dependency"] }

Dapp 2

#![cfg_attr(not(feature = "std"), no_std)]

use ink_lang as ink;

#[ink::contract]
pub mod dapp2 {
    #[ink(storage)]
    pub struct Dapp2 {
        pub what: u8,
    }

    impl Dapp2 {
        #[ink(constructor)]
        pub fn new() -> Self {
            let what = 2.into();
            Self {
                what
            }
        }

        #[ink(message)]
        pub fn do_something(&mut self) -> u8 {
            ink_env::debug_println!("{}", self.what);
            self.what
        }
    }
}

When I run this build, dapp2 compiles but dapp1 fails with

error[E0432]: unresolved import `dapp2`
 --> /home/usr/dev/dapp-example/dapp1/lib.rs:4:5
  |
4 | use dapp2;
  |     ^^^^^ no external crate `dapp2`

Even my IDE is able to find dapp2 when clicking through so what's wrong with this import style?

I've seen other examples (1, 2, 3) where the contracts are simply imported into the module but this doesn't seem to work for me. If I do this, I get:

7 |     use dapp2::Dapp2Ref;
  |         ^^^^^ use of undeclared crate or module `dapp2`

Ink is set to master branch. Rust nightly is up to date. Edition is 2021. The example code is on github


Solution

  • The issue was not having the crate-type set as rlib in the toml files.

    crate-type = [
        # Used for normal contract Wasm blobs.
        "cdylib",
        # This was not set
        "rlib"
    ]
    

    https://github.com/prosopo-io/dapp-example/blob/5b31491bfa02ccd9603c1ac91f0907c2c9b84856/dapp1/Cargo.toml#L25