ink_env/call/
create_builder.rs

1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use core::marker::PhantomData;
16
17use ink_primitives::{
18    abi::{
19        AbiEncodeWith,
20        Sol,
21    },
22    Address,
23    H256,
24    U256,
25};
26
27#[cfg(feature = "unstable-hostfn")]
28use crate::Error;
29use crate::{
30    call::{
31        utils::{
32            DecodeConstructorError,
33            EmptyArgumentList,
34            ReturnType,
35            Set,
36            Unset,
37        },
38        ExecutionInput,
39        Selector,
40    },
41    types::Environment,
42    ContractEnv,
43};
44
45pub mod state {
46    //! Type states that tell what state of a instantiation argument has not
47    //! yet been set properly for a valid construction.
48}
49
50/// Contracts that can be constructed from an `AccountId`.
51///
52/// # Note
53///
54/// This is needed because of conflicting implementations of `From<T> for T`
55/// in the generated code of `ink`.
56///
57/// But it is possible to use `From<AccountId> for T` with [`crate::AccountIdGuard`]
58/// bound.
59pub trait FromAddr {
60    /// Creates the contract instance from the account ID of the already instantiated
61    /// contract.
62    fn from_addr(addr: Address) -> Self;
63}
64
65/// Represents any type that can be returned from an `ink!` constructor. The following
66/// contract implements the four different return type signatures implementing this trait:
67///
68/// - `Self`
69/// - `Result<Self, Error>`
70/// - `Contract`
71/// - `Result<Contract, Error>`
72///
73/// ```rust
74/// #[ink::contract]
75/// mod contract {
76///     #[ink(storage)]
77///     pub struct Contract {}
78///
79///     #[derive(Debug, PartialEq, Eq)]
80///     #[ink::scale_derive(Encode, Decode, TypeInfo)]
81///     pub enum Error {
82///         Foo,
83///     }
84///
85///     impl Contract {
86///         #[ink(constructor)]
87///         pub fn new_self() -> Self {
88///             Self {}
89///         }
90///
91///         #[ink(constructor)]
92///         pub fn new_storage_name() -> Contract {
93///             Contract {}
94///         }
95///
96///         #[ink(constructor)]
97///         pub fn new_result_self() -> Result<Self, Error> {
98///             Ok(Self {})
99///         }
100///
101///         #[ink(constructor)]
102///         pub fn new_result_storage_name() -> Result<Contract, Error> {
103///             Ok(Contract {})
104///         }
105///
106///         #[ink(message)]
107///         pub fn message(&self) {}
108///     }
109/// }
110/// ```
111///
112/// These constructor return signatures are then used by the `ContractRef` codegen for the
113/// [`CreateBuilder::returns`] type parameter.
114pub trait ConstructorReturnType<C, Abi> {
115    /// Is `true` if `Self` is `Result<C, E>`.
116    const IS_RESULT: bool = false;
117
118    /// The actual return type of the constructor.
119    /// - If a constructor returns `Self`, then `Output = Self`
120    /// - If a constructor returns a `Result<Self, E>`, then `Output = Result<Self, E>`
121    type Output;
122
123    /// The error type of the constructor return type.
124    type Error: DecodeConstructorError<Abi>;
125
126    /// Construct a success value of the `Output` type.
127    fn ok(value: C) -> Self::Output;
128
129    /// Construct an error value of the `Output` type.
130    ///
131    /// `Result` implementations should return `Some(Err(err))`, otherwise default to
132    /// `None`.
133    fn err(_err: Self::Error) -> Option<Self::Output> {
134        None
135    }
136}
137
138/// Blanket implementation for `ContractRef` types, generated for cross-contract calls.
139///
140/// In the context of a `ContractRef` inherent, `Self` from a constructor return
141/// type will become the type of the `ContractRef`'s type.
142impl<C, Abi> ConstructorReturnType<C, Abi> for C
143where
144    C: ContractEnv + FromAddr,
145    (): DecodeConstructorError<Abi>,
146{
147    type Output = C;
148    type Error = ();
149
150    fn ok(value: C) -> Self::Output {
151        value
152    }
153}
154
155/// Blanket implementation for a `Result<Self>` return type. `Self` in the context
156/// of a `ContractRef` inherent becomes the `ContractRef`s type.
157impl<C, E, Abi> ConstructorReturnType<C, Abi> for Result<C, E>
158where
159    C: ContractEnv + FromAddr,
160    E: DecodeConstructorError<Abi>,
161{
162    const IS_RESULT: bool = true;
163
164    type Output = Result<C, E>;
165    type Error = E;
166
167    fn ok(value: C) -> Self::Output {
168        Ok(value)
169    }
170
171    fn err(err: Self::Error) -> Option<Self::Output> {
172        Some(Err(err))
173    }
174}
175
176/// Defines the limit params for the new `ext::instantiate` host function.
177/// todo: rename
178#[derive(Clone, Debug)]
179pub struct LimitParamsV2 {
180    ref_time_limit: u64,
181    proof_size_limit: u64,
182    storage_deposit_limit: Option<U256>,
183}
184
185/// Builds up contract instantiations.
186#[derive(Debug)]
187pub struct CreateParams<E, ContractRef, Limits, Args, R, Abi> {
188    /// The code hash of the created contract.
189    code_hash: H256,
190    /// Parameters for weight and storage limits, differs for versions of the instantiate
191    /// host function.
192    limits: Limits,
193    /// The endowment for the instantiated contract.
194    /// todo: is this correct? or is the value here `U256`?
195    endowment: U256,
196    /// The input data for the instantiation.
197    exec_input: ExecutionInput<Args, Abi>,
198    /// The salt for determining the hash for the contract account ID.
199    salt_bytes: Option<[u8; 32]>,
200    /// The return type of the target contract's constructor method.
201    _return_type: ReturnType<R>,
202    /// The type of the reference to the contract returned from the constructor.
203    _phantom: PhantomData<fn() -> (E, ContractRef)>,
204}
205
206impl<E, ContractRef, Limits, Args, R, Abi>
207    CreateParams<E, ContractRef, Limits, Args, R, Abi>
208where
209    E: Environment,
210{
211    /// The code hash of the contract.
212    #[inline]
213    pub fn code_hash(&self) -> &H256 {
214        &self.code_hash
215    }
216
217    /// The endowment for the instantiated contract.
218    #[inline]
219    pub fn endowment(&self) -> &U256 {
220        &self.endowment
221    }
222
223    /// The raw encoded input data.
224    #[inline]
225    pub fn exec_input(&self) -> &ExecutionInput<Args, Abi> {
226        &self.exec_input
227    }
228
229    /// Modify the selector.
230    ///
231    /// Useful when using the [`CreateParams`] generated as part of the
232    /// `ContractRef`, but using a custom selector.
233    pub fn update_selector(&mut self, selector: Selector) {
234        self.exec_input.update_selector(selector)
235    }
236}
237
238impl<E, ContractRef, Args, R, Abi>
239    CreateParams<E, ContractRef, LimitParamsV2, Args, R, Abi>
240where
241    E: Environment,
242{
243    /// Gets the `ref_time_limit` part of the weight limit for the contract instantiation.
244    #[inline]
245    pub fn ref_time_limit(&self) -> u64 {
246        self.limits.ref_time_limit
247    }
248
249    /// Gets the `proof_size_limit` part of the weight limit for the contract
250    /// instantiation.
251    #[inline]
252    pub fn proof_size_limit(&self) -> u64 {
253        self.limits.proof_size_limit
254    }
255
256    /// Gets the `storage_deposit_limit` for the contract instantiation.
257    #[inline]
258    pub fn storage_deposit_limit(&self) -> Option<&U256> {
259        self.limits.storage_deposit_limit.as_ref()
260    }
261}
262
263impl<E, ContractRef, Limits, Args, R, Abi>
264    CreateParams<E, ContractRef, Limits, Args, R, Abi>
265where
266    E: Environment,
267{
268    /// The salt for determining the hash for the contract account ID.
269    #[inline]
270    pub fn salt_bytes(&self) -> &Option<[u8; 32]> {
271        &self.salt_bytes
272    }
273}
274
275impl<E, ContractRef, Args, R, Abi>
276    CreateParams<E, ContractRef, LimitParamsV2, Args, R, Abi>
277where
278    E: Environment,
279    ContractRef: FromAddr + crate::ContractReverseReference,
280    <ContractRef as crate::ContractReverseReference>::Type:
281        crate::reflect::ContractConstructorDecoder,
282    <ContractRef as crate::ContractReverseReference>::Type:
283        crate::reflect::ContractMessageDecoder,
284    Args: AbiEncodeWith<Abi>,
285    R: ConstructorReturnType<ContractRef, Abi>,
286{
287    /// todo
288    /// Instantiates the contract and returns its account ID back to the caller.
289    ///
290    /// # Panics
291    ///
292    /// This method panics if it encounters an [`ink::env::Error`][`crate::Error`] or an
293    /// [`ink::primitives::LangError`][`ink_primitives::LangError`]. If you want to handle
294    /// those use the [`try_instantiate`][`CreateParams::try_instantiate`] method
295    /// instead.
296    #[inline]
297    #[cfg(feature = "unstable-hostfn")]
298    pub fn instantiate(&self) -> <R as ConstructorReturnType<ContractRef, Abi>>::Output {
299        crate::instantiate_contract(self)
300            .unwrap_or_else(|env_error| {
301                panic!("Cross-contract instantiation failed with {env_error:?}")
302            })
303            .unwrap_or_else(|lang_error| {
304                panic!("Received a `LangError` while instantiating: {lang_error:?}")
305            })
306    }
307
308    /// Instantiates the contract and returns its account ID back to the caller.
309    ///
310    /// # Note
311    ///
312    /// On failure this returns an outer [`ink::env::Error`][`crate::Error`] or inner
313    /// [`ink::primitives::LangError`][`ink_primitives::LangError`], both of which can be
314    /// handled by the caller.
315    #[inline]
316    #[cfg(feature = "unstable-hostfn")]
317    pub fn try_instantiate(
318        &self,
319    ) -> Result<
320        ink_primitives::ConstructorResult<
321            <R as ConstructorReturnType<ContractRef, Abi>>::Output,
322        >,
323        Error,
324    > {
325        crate::instantiate_contract(self)
326    }
327}
328
329/// Builds up contract instantiations.
330#[derive(Clone)]
331pub struct CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
332where
333    E: Environment,
334{
335    code_hash: H256,
336    limits: Limits,
337    endowment: U256,
338    exec_input: Args,
339    salt: Option<[u8; 32]>,
340    return_type: RetType,
341    #[allow(clippy::type_complexity)]
342    _phantom: PhantomData<fn() -> (E, ContractRef, Abi)>,
343}
344
345/// Returns a new [`CreateBuilder`] to build up the parameters to a cross-contract
346/// instantiation that uses the "default" ABI for calls for the ink! project.
347///
348/// # Note
349///
350/// The "default" ABI for calls is "ink", unless the ABI is set to "sol"
351/// in the ink! project's manifest file (i.e. `Cargo.toml`).
352///
353/// # Example
354///
355/// **Note:** The shown examples panic because there is currently no cross-calling
356///           support in the off-chain testing environment. However, this code
357///           should work fine in on-chain environments.
358///
359/// ## Example 1: Returns Address of Instantiated Contract
360///
361/// The below example shows instantiation of contract of type `MyContract`.
362///
363/// The used constructor:
364///
365/// - has a selector equal to `0xDEADBEEF`
366/// - is provided with 4000 units of gas for its execution
367/// - is provided with 25 units of transferred value for the new contract instance
368/// - receives the following arguments in order 1. an `i32` with value `42` 2. a `bool`
369///   with value `true` 3. an array of 32 `u8` with value `0x10`
370///
371/// ```should_panic
372/// # use ::ink_env::{
373/// #     Environment,
374/// #     DefaultEnvironment,
375/// #     call::{build_create, Selector, ExecutionInput, FromAddr}
376/// # };
377/// # type Hash = <DefaultEnvironment as Environment>::Hash;
378/// #
379/// # #[ink::contract]
380/// # pub mod contract {
381/// #     #[ink(storage)]
382/// #     pub struct MyContract {}
383/// #
384/// #     impl MyContract {
385/// #         #[ink(constructor)]
386/// #         pub fn my_constructor() -> Self { Self {} }
387/// #
388/// #         #[ink(message)]
389/// #         pub fn message(&self) {}
390/// #     }
391/// # }
392/// # use contract::MyContractRef;
393/// let my_contract: MyContractRef = build_create::<MyContractRef>()
394///     .code_hash(ink::H256::from([0x42; 32]))
395///     .endowment(25.into())
396///     .exec_input(
397///         ExecutionInput::new(Selector::new(ink::selector_bytes!("my_constructor")))
398///             .push_arg(42)
399///             .push_arg(true)
400///             .push_arg(&[0x10u8; 32]),
401///     )
402///     .salt_bytes(Some([1u8; 32]))
403///     .returns::<MyContractRef>()
404///     .instantiate();
405/// ```
406///
407/// ## Example 2: Handles Result from Fallible Constructor
408///
409/// ```should_panic
410/// # use ::ink_env::{
411/// #     Environment,
412/// #     DefaultEnvironment,
413/// #     call::{build_create, Selector, ExecutionInput, FromAddr}
414/// # };
415/// # type Hash = <DefaultEnvironment as Environment>::Hash;
416/// #
417/// # #[ink::contract]
418/// # pub mod contract {
419/// #     #[derive(scale::Encode, scale::Decode, Debug)]
420/// #     #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
421/// #     pub struct ConstructorError;
422/// #
423/// #     #[ink(storage)]
424/// #     pub struct MyContract {}
425/// #
426/// #     impl MyContract {
427/// #         #[ink(constructor)]
428/// #         pub fn my_constructor() -> Result<Self, ConstructorError> {
429/// #             Ok(Self {})
430/// #         }
431/// #
432/// #         #[ink(message)]
433/// #         pub fn message(&self) {}
434/// #     }
435/// # }
436/// # use contract::{MyContractRef, ConstructorError};
437/// let my_contract: MyContractRef = build_create::<MyContractRef>()
438///     .code_hash(ink::H256::from([0x42; 32]))
439///     .endowment(25.into())
440///     .exec_input(
441///         ExecutionInput::new(Selector::new(ink::selector_bytes!("my_constructor")))
442///             .push_arg(42)
443///             .push_arg(true)
444///             .push_arg(&[0x10u8; 32]),
445///     )
446///     .salt_bytes(Some([1u8; 32]))
447///     .returns::<Result<MyContractRef, ConstructorError>>()
448///     .instantiate()
449///     .expect("Constructor should have executed successfully.");
450/// ```
451#[allow(clippy::type_complexity)]
452pub fn build_create<ContractRef>() -> CreateBuilder<
453    <ContractRef as ContractEnv>::Env,
454    ContractRef,
455    Set<LimitParamsV2>,
456    Unset<ExecutionInput<EmptyArgumentList<crate::DefaultAbi>, crate::DefaultAbi>>,
457    Unset<ReturnType<()>>,
458    crate::DefaultAbi,
459>
460where
461    ContractRef: ContractEnv,
462{
463    CreateBuilder {
464        code_hash: Default::default(),
465        limits: Set(LimitParamsV2 {
466            ref_time_limit: u64::MAX,
467            proof_size_limit: u64::MAX,
468            storage_deposit_limit: None,
469        }),
470        endowment: Default::default(),
471        exec_input: Default::default(),
472        salt: Default::default(),
473        return_type: Default::default(),
474        _phantom: Default::default(),
475    }
476}
477
478/// Returns a new [`CreateBuilder`] for the specified ABI to build up the parameters to a
479/// cross-contract instantiation.
480/// See [`build_create`] for more details on usage.
481#[allow(clippy::type_complexity)]
482pub fn build_create_abi<ContractRef, Abi>() -> CreateBuilder<
483    <ContractRef as ContractEnv>::Env,
484    ContractRef,
485    Set<LimitParamsV2>,
486    Unset<ExecutionInput<EmptyArgumentList<Abi>, Abi>>,
487    Unset<ReturnType<()>>,
488    Abi,
489>
490where
491    ContractRef: ContractEnv,
492{
493    CreateBuilder {
494        code_hash: Default::default(),
495        limits: Set(LimitParamsV2 {
496            ref_time_limit: u64::MAX,
497            proof_size_limit: u64::MAX,
498            storage_deposit_limit: None,
499        }),
500        endowment: Default::default(),
501        exec_input: Default::default(),
502        salt: Default::default(),
503        return_type: Default::default(),
504        _phantom: Default::default(),
505    }
506}
507
508/// Returns a new [`CreateBuilder`] to build up the parameters to a cross-contract
509/// instantiation that uses Solidity ABI Encoding.
510/// See [`build_create`] for more details on usage.
511#[allow(clippy::type_complexity)]
512pub fn build_create_solidity<ContractRef>() -> CreateBuilder<
513    <ContractRef as ContractEnv>::Env,
514    ContractRef,
515    Set<LimitParamsV2>,
516    Unset<ExecutionInput<EmptyArgumentList<Sol>, Sol>>,
517    Unset<ReturnType<()>>,
518    Sol,
519>
520where
521    ContractRef: ContractEnv,
522{
523    CreateBuilder {
524        code_hash: Default::default(),
525        limits: Set(LimitParamsV2 {
526            ref_time_limit: u64::MAX,
527            proof_size_limit: u64::MAX,
528            storage_deposit_limit: None,
529        }),
530        endowment: Default::default(),
531        exec_input: Default::default(),
532        salt: Default::default(),
533        return_type: Default::default(),
534        _phantom: Default::default(),
535    }
536}
537
538impl<E, ContractRef, Limits, Args, RetType, Abi>
539    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
540where
541    E: Environment,
542{
543    /// Sets the used code hash for the contract instantiation.
544    #[inline]
545    pub fn code_hash(
546        self,
547        code_hash: H256,
548    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
549        CreateBuilder {
550            code_hash,
551            limits: self.limits,
552            endowment: self.endowment,
553            exec_input: self.exec_input,
554            salt: self.salt,
555            return_type: self.return_type,
556            _phantom: Default::default(),
557        }
558    }
559}
560
561impl<E, ContractRef, Args, RetType, Abi>
562    CreateBuilder<E, ContractRef, Set<LimitParamsV2>, Args, RetType, Abi>
563where
564    E: Environment,
565{
566    /// Sets the `ref_time_limit` part of the weight limit for the contract instantiation.
567    #[inline]
568    pub fn ref_time_limit(self, ref_time_limit: u64) -> Self {
569        CreateBuilder {
570            limits: Set(LimitParamsV2 {
571                ref_time_limit,
572                ..self.limits.value()
573            }),
574            ..self
575        }
576    }
577
578    /// Sets the `proof_size_limit` part of the weight limit for the contract
579    /// instantiation.
580    #[inline]
581    pub fn proof_size_limit(self, proof_size_limit: u64) -> Self {
582        CreateBuilder {
583            limits: Set(LimitParamsV2 {
584                proof_size_limit,
585                ..self.limits.value()
586            }),
587            ..self
588        }
589    }
590
591    /// Sets the `storage_deposit_limit` for the contract instantiation.
592    #[inline]
593    pub fn storage_deposit_limit(self, storage_deposit_limit: U256) -> Self {
594        CreateBuilder {
595            limits: Set(LimitParamsV2 {
596                storage_deposit_limit: Some(storage_deposit_limit),
597                ..self.limits.value()
598            }),
599            ..self
600        }
601    }
602}
603
604impl<E, ContractRef, Limits, Args, RetType, Abi>
605    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
606where
607    E: Environment,
608{
609    /// Sets the value transferred upon the execution of the call.
610    #[inline]
611    pub fn endowment(
612        self,
613        endowment: U256,
614    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
615        CreateBuilder {
616            code_hash: self.code_hash,
617            limits: self.limits,
618            endowment,
619            exec_input: self.exec_input,
620            salt: self.salt,
621            return_type: self.return_type,
622            _phantom: Default::default(),
623        }
624    }
625}
626
627impl<E, ContractRef, Limits, RetType, Abi>
628    CreateBuilder<
629        E,
630        ContractRef,
631        Limits,
632        Unset<ExecutionInput<EmptyArgumentList<Abi>, Abi>>,
633        RetType,
634        Abi,
635    >
636where
637    E: Environment,
638{
639    /// Sets the value transferred upon the execution of the call.
640    #[inline]
641    pub fn exec_input<Args>(
642        self,
643        exec_input: ExecutionInput<Args, Abi>,
644    ) -> CreateBuilder<E, ContractRef, Limits, Set<ExecutionInput<Args, Abi>>, RetType, Abi>
645    {
646        CreateBuilder {
647            code_hash: self.code_hash,
648            limits: self.limits,
649            endowment: self.endowment,
650            exec_input: Set(exec_input),
651            salt: self.salt,
652            return_type: self.return_type,
653            _phantom: Default::default(),
654        }
655    }
656}
657
658impl<E, ContractRef, Limits, Args, RetType, Abi>
659    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
660where
661    E: Environment,
662{
663    /// Sets the salt used for the execution of the call.
664    #[inline]
665    pub fn salt_bytes(
666        self,
667        salt: Option<[u8; 32]>,
668    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
669        CreateBuilder {
670            code_hash: self.code_hash,
671            limits: self.limits,
672            endowment: self.endowment,
673            exec_input: self.exec_input,
674            salt,
675            return_type: self.return_type,
676            _phantom: Default::default(),
677        }
678    }
679}
680
681impl<E, ContractRef, Limits, Args, Abi>
682    CreateBuilder<E, ContractRef, Limits, Args, Unset<ReturnType<()>>, Abi>
683where
684    E: Environment,
685{
686    /// Sets the type of the returned value upon the execution of the constructor.
687    ///
688    /// # Note
689    ///
690    /// Constructors are not able to return arbitrary values. Instead, a successful call
691    /// to a constructor returns the address at which the contract was instantiated.
692    ///
693    /// Therefore this must always be a reference (i.e. `ContractRef`) to the contract
694    /// you're trying to instantiate.
695    #[inline]
696    pub fn returns<R>(
697        self,
698    ) -> CreateBuilder<E, ContractRef, Limits, Args, Set<ReturnType<R>>, Abi>
699    where
700        ContractRef: FromAddr,
701        R: ConstructorReturnType<ContractRef, Abi>,
702    {
703        CreateBuilder {
704            code_hash: self.code_hash,
705            limits: self.limits,
706            endowment: self.endowment,
707            exec_input: self.exec_input,
708            salt: self.salt,
709            return_type: Set(Default::default()),
710            _phantom: Default::default(),
711        }
712    }
713}
714
715impl<E, ContractRef, Limits, Args, RetType, Abi>
716    CreateBuilder<
717        E,
718        ContractRef,
719        Set<Limits>,
720        Set<ExecutionInput<Args, Abi>>,
721        Set<ReturnType<RetType>>,
722        Abi,
723    >
724where
725    E: Environment,
726{
727    /// Finalizes the `CreateBuilder`, allowing it to instantiate a contract.
728    #[inline]
729    pub fn params(self) -> CreateParams<E, ContractRef, Limits, Args, RetType, Abi> {
730        CreateParams {
731            code_hash: self.code_hash,
732            limits: self.limits.value(),
733            endowment: self.endowment,
734            exec_input: self.exec_input.value(),
735            salt_bytes: self.salt,
736            _return_type: Default::default(),
737            _phantom: Default::default(),
738        }
739    }
740}
741
742impl<E, ContractRef, Args, RetType, Abi>
743    CreateBuilder<
744        E,
745        ContractRef,
746        Set<LimitParamsV2>,
747        Set<ExecutionInput<Args, Abi>>,
748        Set<ReturnType<RetType>>,
749        Abi,
750    >
751where
752    E: Environment,
753    ContractRef: FromAddr + crate::ContractReverseReference,
754    <ContractRef as crate::ContractReverseReference>::Type:
755        crate::reflect::ContractConstructorDecoder,
756    <ContractRef as crate::ContractReverseReference>::Type:
757        crate::reflect::ContractMessageDecoder,
758    Args: AbiEncodeWith<Abi>,
759    RetType: ConstructorReturnType<ContractRef, Abi>,
760{
761    /// todo check comment
762    /// Instantiates the contract and returns its account ID back to the caller.
763    ///
764    /// # Panics
765    ///
766    /// This method panics if it encounters an [`ink::env::Error`][`crate::Error`] or an
767    /// [`ink::primitives::LangError`][`ink_primitives::LangError`]. If you want to handle
768    /// those use the [`try_instantiate`][`CreateBuilder::try_instantiate`] method
769    /// instead.
770    #[inline]
771    #[cfg(feature = "unstable-hostfn")]
772    pub fn instantiate(
773        self,
774    ) -> <RetType as ConstructorReturnType<ContractRef, Abi>>::Output {
775        self.params().instantiate()
776    }
777
778    /// todo check comment
779    /// Instantiates the contract and returns its account ID back to the caller.
780    ///
781    /// # Note
782    ///
783    /// On failure this returns an outer [`ink::env::Error`][`crate::Error`] or inner
784    /// [`ink::primitives::LangError`][`ink_primitives::LangError`], both of which can be
785    /// handled by the caller.
786    #[inline]
787    #[cfg(feature = "unstable-hostfn")]
788    pub fn try_instantiate(
789        self,
790    ) -> Result<
791        ink_primitives::ConstructorResult<
792            <RetType as ConstructorReturnType<ContractRef, Abi>>::Output,
793        >,
794        Error,
795    > {
796        self.params().try_instantiate()
797    }
798}