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    Address,
19    H256,
20    U256,
21    abi::{
22        Ink,
23        Sol,
24    },
25};
26
27use crate::{
28    ContractEnv,
29    Error,
30    call::{
31        ExecutionInput,
32        Selector,
33        utils::{
34            DecodeConstructorError,
35            EmptyArgumentList,
36            EncodeArgsWith,
37            ReturnType,
38            Set,
39            Unset,
40        },
41    },
42    types::Environment,
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: EncodeArgsWith<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    pub fn instantiate(&self) -> <R as ConstructorReturnType<ContractRef, Abi>>::Output {
298        crate::instantiate_contract(self)
299            .unwrap_or_else(|env_error| {
300                panic!("Cross-contract instantiation failed with {env_error:?}")
301            })
302            .unwrap_or_else(|lang_error| {
303                panic!("Received a `LangError` while instantiating: {lang_error:?}")
304            })
305    }
306
307    /// Instantiates the contract and returns its account ID back to the caller.
308    ///
309    /// # Note
310    ///
311    /// On failure this returns an outer [`ink::env::Error`][`crate::Error`] or inner
312    /// [`ink::primitives::LangError`][`ink_primitives::LangError`], both of which can be
313    /// handled by the caller.
314    #[inline]
315    pub fn try_instantiate(
316        &self,
317    ) -> Result<
318        ink_primitives::ConstructorResult<
319            <R as ConstructorReturnType<ContractRef, Abi>>::Output,
320        >,
321        Error,
322    > {
323        crate::instantiate_contract(self)
324    }
325}
326
327/// Builds up contract instantiations.
328#[derive(Clone)]
329pub struct CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
330where
331    E: Environment,
332{
333    code_hash: H256,
334    limits: Limits,
335    endowment: U256,
336    exec_input: Args,
337    salt: Option<[u8; 32]>,
338    return_type: RetType,
339    #[allow(clippy::type_complexity)]
340    _phantom: PhantomData<fn() -> (E, ContractRef, Abi)>,
341}
342
343/// Returns a new [`CreateBuilder`] to build up the parameters to a cross-contract
344/// instantiation that uses the "default" ABI for calls for the ink! project.
345///
346/// # Note
347///
348/// The "default" ABI for calls is "ink", unless the ABI is set to "sol"
349/// in the ink! project's manifest file (i.e. `Cargo.toml`).
350///
351/// # Example
352///
353/// **Note:** The shown examples panic because there is currently no cross-calling
354///           support in the off-chain testing environment. However, this code
355///           should work fine in on-chain environments.
356///
357/// ## Example 1: Returns Address of Instantiated Contract
358///
359/// The below example shows instantiation of contract of type `MyContract`.
360///
361/// The used constructor:
362///
363/// - has a selector equal to `0xDEADBEEF`
364/// - is provided with 4000 units of gas for its execution
365/// - is provided with 25 units of transferred value for the new contract instance
366/// - receives the following arguments in order 1. an `i32` with value `42` 2. a `bool`
367///   with value `true` 3. an array of 32 `u8` with value `0x10`
368///
369/// ```should_panic
370/// # use ::ink_env::{
371/// #     Environment,
372/// #     DefaultEnvironment,
373/// #     call::{build_create, Selector, ExecutionInput, FromAddr}
374/// # };
375/// # type Hash = <DefaultEnvironment as Environment>::Hash;
376/// #
377/// # #[ink::contract]
378/// # pub mod contract {
379/// #     #[ink(storage)]
380/// #     pub struct MyContract {}
381/// #
382/// #     impl MyContract {
383/// #         #[ink(constructor)]
384/// #         pub fn my_constructor() -> Self { Self {} }
385/// #
386/// #         #[ink(message)]
387/// #         pub fn message(&self) {}
388/// #     }
389/// # }
390/// #
391/// let my_contract: MyContractRef = build_create::<MyContractRef>()
392///     .code_hash(ink::H256::from([0x42; 32]))
393///     .endowment(25.into())
394///     .exec_input(
395///         ExecutionInput::new(Selector::new(ink::selector_bytes!(
396///             Abi::Ink,
397///             "my_constructor"
398///         )))
399///         .push_arg(42)
400///         .push_arg(true)
401///         .push_arg(&[0x10u8; 32]),
402///     )
403///     .salt_bytes(Some([1u8; 32]))
404///     .returns::<MyContractRef>()
405///     .instantiate();
406/// ```
407///
408/// ## Example 2: Handles Result from Fallible Constructor
409///
410/// ```should_panic
411/// # use ::ink_env::{
412/// #     Environment,
413/// #     DefaultEnvironment,
414/// #     call::{build_create, Selector, ExecutionInput, FromAddr}
415/// # };
416/// # type Hash = <DefaultEnvironment as Environment>::Hash;
417/// #
418/// # #[ink::contract]
419/// # pub mod contract {
420/// #     #[derive(scale::Encode, scale::Decode, Debug)]
421/// #     #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
422/// #     pub struct ConstructorError;
423/// #
424/// #     #[ink(storage)]
425/// #     pub struct MyContract {}
426/// #
427/// #     impl MyContract {
428/// #         #[ink(constructor)]
429/// #         pub fn my_constructor() -> Result<Self, ConstructorError> {
430/// #             Ok(Self {})
431/// #         }
432/// #
433/// #         #[ink(message)]
434/// #         pub fn message(&self) {}
435/// #     }
436/// # }
437/// # use contract::ConstructorError;
438/// let my_contract: MyContractRef = build_create::<MyContractRef>()
439///     .code_hash(ink::H256::from([0x42; 32]))
440///     .endowment(25.into())
441///     .exec_input(
442///         ExecutionInput::new(Selector::new(ink::selector_bytes!(
443///             Abi::Ink,
444///             "my_constructor"
445///         )))
446///         .push_arg(42)
447///         .push_arg(true)
448///         .push_arg(&[0x10u8; 32]),
449///     )
450///     .salt_bytes(Some([1u8; 32]))
451///     .returns::<Result<MyContractRef, ConstructorError>>()
452///     .instantiate()
453///     .expect("Constructor should have executed successfully.");
454/// ```
455#[allow(clippy::type_complexity)]
456pub fn build_create<ContractRef>() -> CreateBuilder<
457    <ContractRef as ContractEnv>::Env,
458    ContractRef,
459    Set<LimitParamsV2>,
460    Unset<ExecutionInput<EmptyArgumentList<crate::DefaultAbi>, crate::DefaultAbi>>,
461    Unset<ReturnType<()>>,
462    crate::DefaultAbi,
463>
464where
465    ContractRef: ContractEnv,
466{
467    CreateBuilder {
468        code_hash: Default::default(),
469        limits: Set(LimitParamsV2 {
470            ref_time_limit: u64::MAX,
471            proof_size_limit: u64::MAX,
472            storage_deposit_limit: None,
473        }),
474        endowment: Default::default(),
475        exec_input: Default::default(),
476        salt: Default::default(),
477        return_type: Default::default(),
478        _phantom: Default::default(),
479    }
480}
481
482/// Returns a new [`CreateBuilder`] to build up the parameters to a cross-contract
483/// instantiation that uses ink! ABI Encoding (i.e. with SCALE codec for input/output
484/// encode/decode).
485///
486/// See [`build_create`] for more details on usage.
487#[allow(clippy::type_complexity)]
488pub fn build_create_ink<ContractRef>() -> CreateBuilder<
489    <ContractRef as ContractEnv>::Env,
490    ContractRef,
491    Set<LimitParamsV2>,
492    Unset<ExecutionInput<EmptyArgumentList<Ink>, Ink>>,
493    Unset<ReturnType<()>>,
494    Ink,
495>
496where
497    ContractRef: ContractEnv,
498{
499    CreateBuilder {
500        code_hash: Default::default(),
501        limits: Set(LimitParamsV2 {
502            ref_time_limit: u64::MAX,
503            proof_size_limit: u64::MAX,
504            storage_deposit_limit: None,
505        }),
506        endowment: Default::default(),
507        exec_input: Default::default(),
508        salt: Default::default(),
509        return_type: Default::default(),
510        _phantom: Default::default(),
511    }
512}
513
514/// Returns a new [`CreateBuilder`] to build up the parameters to a cross-contract
515/// instantiation that uses Solidity ABI Encoding.
516///
517/// See [`build_create`] for more details on usage.
518#[allow(clippy::type_complexity)]
519pub fn build_create_sol<ContractRef>() -> CreateBuilder<
520    <ContractRef as ContractEnv>::Env,
521    ContractRef,
522    Set<LimitParamsV2>,
523    Unset<ExecutionInput<EmptyArgumentList<Sol>, Sol>>,
524    Unset<ReturnType<()>>,
525    Sol,
526>
527where
528    ContractRef: ContractEnv,
529{
530    CreateBuilder {
531        code_hash: Default::default(),
532        limits: Set(LimitParamsV2 {
533            ref_time_limit: u64::MAX,
534            proof_size_limit: u64::MAX,
535            storage_deposit_limit: None,
536        }),
537        endowment: Default::default(),
538        exec_input: Default::default(),
539        salt: Default::default(),
540        return_type: Default::default(),
541        _phantom: Default::default(),
542    }
543}
544
545impl<E, ContractRef, Limits, Args, RetType, Abi>
546    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
547where
548    E: Environment,
549{
550    /// Sets the used code hash for the contract instantiation.
551    #[inline]
552    pub fn code_hash(
553        self,
554        code_hash: H256,
555    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
556        CreateBuilder {
557            code_hash,
558            limits: self.limits,
559            endowment: self.endowment,
560            exec_input: self.exec_input,
561            salt: self.salt,
562            return_type: self.return_type,
563            _phantom: Default::default(),
564        }
565    }
566}
567
568impl<E, ContractRef, Args, RetType, Abi>
569    CreateBuilder<E, ContractRef, Set<LimitParamsV2>, Args, RetType, Abi>
570where
571    E: Environment,
572{
573    /// Sets the `ref_time_limit` part of the weight limit for the contract instantiation.
574    #[inline]
575    pub fn ref_time_limit(self, ref_time_limit: u64) -> Self {
576        CreateBuilder {
577            limits: Set(LimitParamsV2 {
578                ref_time_limit,
579                ..self.limits.value()
580            }),
581            ..self
582        }
583    }
584
585    /// Sets the `proof_size_limit` part of the weight limit for the contract
586    /// instantiation.
587    #[inline]
588    pub fn proof_size_limit(self, proof_size_limit: u64) -> Self {
589        CreateBuilder {
590            limits: Set(LimitParamsV2 {
591                proof_size_limit,
592                ..self.limits.value()
593            }),
594            ..self
595        }
596    }
597
598    /// Sets the `storage_deposit_limit` for the contract instantiation.
599    #[inline]
600    pub fn storage_deposit_limit(self, storage_deposit_limit: U256) -> Self {
601        CreateBuilder {
602            limits: Set(LimitParamsV2 {
603                storage_deposit_limit: Some(storage_deposit_limit),
604                ..self.limits.value()
605            }),
606            ..self
607        }
608    }
609}
610
611impl<E, ContractRef, Limits, Args, RetType, Abi>
612    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
613where
614    E: Environment,
615{
616    /// Sets the value transferred upon the execution of the call.
617    #[inline]
618    pub fn endowment(
619        self,
620        endowment: U256,
621    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
622        CreateBuilder {
623            code_hash: self.code_hash,
624            limits: self.limits,
625            endowment,
626            exec_input: self.exec_input,
627            salt: self.salt,
628            return_type: self.return_type,
629            _phantom: Default::default(),
630        }
631    }
632}
633
634impl<E, ContractRef, Limits, RetType, Abi>
635    CreateBuilder<
636        E,
637        ContractRef,
638        Limits,
639        Unset<ExecutionInput<EmptyArgumentList<Abi>, Abi>>,
640        RetType,
641        Abi,
642    >
643where
644    E: Environment,
645{
646    /// Sets the value transferred upon the execution of the call.
647    #[inline]
648    pub fn exec_input<Args>(
649        self,
650        exec_input: ExecutionInput<Args, Abi>,
651    ) -> CreateBuilder<E, ContractRef, Limits, Set<ExecutionInput<Args, Abi>>, RetType, Abi>
652    {
653        CreateBuilder {
654            code_hash: self.code_hash,
655            limits: self.limits,
656            endowment: self.endowment,
657            exec_input: Set(exec_input),
658            salt: self.salt,
659            return_type: self.return_type,
660            _phantom: Default::default(),
661        }
662    }
663}
664
665impl<E, ContractRef, Limits, Args, RetType, Abi>
666    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
667where
668    E: Environment,
669{
670    /// Sets the salt used for the execution of the call.
671    #[inline]
672    pub fn salt_bytes(
673        self,
674        salt: Option<[u8; 32]>,
675    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
676        CreateBuilder {
677            code_hash: self.code_hash,
678            limits: self.limits,
679            endowment: self.endowment,
680            exec_input: self.exec_input,
681            salt,
682            return_type: self.return_type,
683            _phantom: Default::default(),
684        }
685    }
686}
687
688impl<E, ContractRef, Limits, Args, Abi>
689    CreateBuilder<E, ContractRef, Limits, Args, Unset<ReturnType<()>>, Abi>
690where
691    E: Environment,
692{
693    /// Sets the type of the returned value upon the execution of the constructor.
694    ///
695    /// # Note
696    ///
697    /// Constructors are not able to return arbitrary values. Instead, a successful call
698    /// to a constructor returns the address at which the contract was instantiated.
699    ///
700    /// Therefore this must always be a reference (i.e. `ContractRef`) to the contract
701    /// you're trying to instantiate.
702    #[inline]
703    pub fn returns<R>(
704        self,
705    ) -> CreateBuilder<E, ContractRef, Limits, Args, Set<ReturnType<R>>, Abi>
706    where
707        ContractRef: FromAddr,
708        R: ConstructorReturnType<ContractRef, Abi>,
709    {
710        CreateBuilder {
711            code_hash: self.code_hash,
712            limits: self.limits,
713            endowment: self.endowment,
714            exec_input: self.exec_input,
715            salt: self.salt,
716            return_type: Set(Default::default()),
717            _phantom: Default::default(),
718        }
719    }
720}
721
722impl<E, ContractRef, Limits, Args, RetType, Abi>
723    CreateBuilder<
724        E,
725        ContractRef,
726        Set<Limits>,
727        Set<ExecutionInput<Args, Abi>>,
728        Set<ReturnType<RetType>>,
729        Abi,
730    >
731where
732    E: Environment,
733{
734    /// Finalizes the `CreateBuilder`, allowing it to instantiate a contract.
735    #[inline]
736    pub fn params(self) -> CreateParams<E, ContractRef, Limits, Args, RetType, Abi> {
737        CreateParams {
738            code_hash: self.code_hash,
739            limits: self.limits.value(),
740            endowment: self.endowment,
741            exec_input: self.exec_input.value(),
742            salt_bytes: self.salt,
743            _return_type: Default::default(),
744            _phantom: Default::default(),
745        }
746    }
747}
748
749impl<E, ContractRef, Args, RetType, Abi>
750    CreateBuilder<
751        E,
752        ContractRef,
753        Set<LimitParamsV2>,
754        Set<ExecutionInput<Args, Abi>>,
755        Set<ReturnType<RetType>>,
756        Abi,
757    >
758where
759    E: Environment,
760    ContractRef: FromAddr + crate::ContractReverseReference,
761    <ContractRef as crate::ContractReverseReference>::Type:
762        crate::reflect::ContractConstructorDecoder,
763    <ContractRef as crate::ContractReverseReference>::Type:
764        crate::reflect::ContractMessageDecoder,
765    Args: EncodeArgsWith<Abi>,
766    RetType: ConstructorReturnType<ContractRef, Abi>,
767{
768    /// todo check comment
769    /// Instantiates the contract and returns its account ID back to the caller.
770    ///
771    /// # Panics
772    ///
773    /// This method panics if it encounters an [`ink::env::Error`][`crate::Error`] or an
774    /// [`ink::primitives::LangError`][`ink_primitives::LangError`]. If you want to handle
775    /// those use the [`try_instantiate`][`CreateBuilder::try_instantiate`] method
776    /// instead.
777    #[inline]
778    pub fn instantiate(
779        self,
780    ) -> <RetType as ConstructorReturnType<ContractRef, Abi>>::Output {
781        self.params().instantiate()
782    }
783
784    /// todo check comment
785    /// Instantiates the contract and returns its account ID back to the caller.
786    ///
787    /// # Note
788    ///
789    /// On failure this returns an outer [`ink::env::Error`][`crate::Error`] or inner
790    /// [`ink::primitives::LangError`][`ink_primitives::LangError`], both of which can be
791    /// handled by the caller.
792    #[inline]
793    pub fn try_instantiate(
794        self,
795    ) -> Result<
796        ink_primitives::ConstructorResult<
797            <RetType as ConstructorReturnType<ContractRef, Abi>>::Output,
798        >,
799        Error,
800    > {
801        self.params().try_instantiate()
802    }
803}