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        AbiEncodeWith,
23        Ink,
24        Sol,
25    },
26};
27
28use crate::{
29    ContractEnv,
30    Error,
31    call::{
32        ExecutionInput,
33        Selector,
34        utils::{
35            DecodeConstructorError,
36            EmptyArgumentList,
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: 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    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/// # use contract::MyContractRef;
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!("my_constructor")))
396///             .push_arg(42)
397///             .push_arg(true)
398///             .push_arg(&[0x10u8; 32]),
399///     )
400///     .salt_bytes(Some([1u8; 32]))
401///     .returns::<MyContractRef>()
402///     .instantiate();
403/// ```
404///
405/// ## Example 2: Handles Result from Fallible Constructor
406///
407/// ```should_panic
408/// # use ::ink_env::{
409/// #     Environment,
410/// #     DefaultEnvironment,
411/// #     call::{build_create, Selector, ExecutionInput, FromAddr}
412/// # };
413/// # type Hash = <DefaultEnvironment as Environment>::Hash;
414/// #
415/// # #[ink::contract]
416/// # pub mod contract {
417/// #     #[derive(scale::Encode, scale::Decode, Debug)]
418/// #     #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
419/// #     pub struct ConstructorError;
420/// #
421/// #     #[ink(storage)]
422/// #     pub struct MyContract {}
423/// #
424/// #     impl MyContract {
425/// #         #[ink(constructor)]
426/// #         pub fn my_constructor() -> Result<Self, ConstructorError> {
427/// #             Ok(Self {})
428/// #         }
429/// #
430/// #         #[ink(message)]
431/// #         pub fn message(&self) {}
432/// #     }
433/// # }
434/// # use contract::{MyContractRef, ConstructorError};
435/// let my_contract: MyContractRef = build_create::<MyContractRef>()
436///     .code_hash(ink::H256::from([0x42; 32]))
437///     .endowment(25.into())
438///     .exec_input(
439///         ExecutionInput::new(Selector::new(ink::selector_bytes!("my_constructor")))
440///             .push_arg(42)
441///             .push_arg(true)
442///             .push_arg(&[0x10u8; 32]),
443///     )
444///     .salt_bytes(Some([1u8; 32]))
445///     .returns::<Result<MyContractRef, ConstructorError>>()
446///     .instantiate()
447///     .expect("Constructor should have executed successfully.");
448/// ```
449#[allow(clippy::type_complexity)]
450pub fn build_create<ContractRef>() -> CreateBuilder<
451    <ContractRef as ContractEnv>::Env,
452    ContractRef,
453    Set<LimitParamsV2>,
454    Unset<ExecutionInput<EmptyArgumentList<crate::DefaultAbi>, crate::DefaultAbi>>,
455    Unset<ReturnType<()>>,
456    crate::DefaultAbi,
457>
458where
459    ContractRef: ContractEnv,
460{
461    CreateBuilder {
462        code_hash: Default::default(),
463        limits: Set(LimitParamsV2 {
464            ref_time_limit: u64::MAX,
465            proof_size_limit: u64::MAX,
466            storage_deposit_limit: None,
467        }),
468        endowment: Default::default(),
469        exec_input: Default::default(),
470        salt: Default::default(),
471        return_type: Default::default(),
472        _phantom: Default::default(),
473    }
474}
475
476/// Returns a new [`CreateBuilder`] to build up the parameters to a cross-contract
477/// instantiation that uses ink! ABI Encoding (i.e. with SCALE codec for input/output
478/// encode/decode).
479///
480/// See [`build_create`] for more details on usage.
481#[allow(clippy::type_complexity)]
482pub fn build_create_ink<ContractRef>() -> CreateBuilder<
483    <ContractRef as ContractEnv>::Env,
484    ContractRef,
485    Set<LimitParamsV2>,
486    Unset<ExecutionInput<EmptyArgumentList<Ink>, Ink>>,
487    Unset<ReturnType<()>>,
488    Ink,
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///
511/// See [`build_create`] for more details on usage.
512#[allow(clippy::type_complexity)]
513pub fn build_create_sol<ContractRef>() -> CreateBuilder<
514    <ContractRef as ContractEnv>::Env,
515    ContractRef,
516    Set<LimitParamsV2>,
517    Unset<ExecutionInput<EmptyArgumentList<Sol>, Sol>>,
518    Unset<ReturnType<()>>,
519    Sol,
520>
521where
522    ContractRef: ContractEnv,
523{
524    CreateBuilder {
525        code_hash: Default::default(),
526        limits: Set(LimitParamsV2 {
527            ref_time_limit: u64::MAX,
528            proof_size_limit: u64::MAX,
529            storage_deposit_limit: None,
530        }),
531        endowment: Default::default(),
532        exec_input: Default::default(),
533        salt: Default::default(),
534        return_type: Default::default(),
535        _phantom: Default::default(),
536    }
537}
538
539impl<E, ContractRef, Limits, Args, RetType, Abi>
540    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
541where
542    E: Environment,
543{
544    /// Sets the used code hash for the contract instantiation.
545    #[inline]
546    pub fn code_hash(
547        self,
548        code_hash: H256,
549    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
550        CreateBuilder {
551            code_hash,
552            limits: self.limits,
553            endowment: self.endowment,
554            exec_input: self.exec_input,
555            salt: self.salt,
556            return_type: self.return_type,
557            _phantom: Default::default(),
558        }
559    }
560}
561
562impl<E, ContractRef, Args, RetType, Abi>
563    CreateBuilder<E, ContractRef, Set<LimitParamsV2>, Args, RetType, Abi>
564where
565    E: Environment,
566{
567    /// Sets the `ref_time_limit` part of the weight limit for the contract instantiation.
568    #[inline]
569    pub fn ref_time_limit(self, ref_time_limit: u64) -> Self {
570        CreateBuilder {
571            limits: Set(LimitParamsV2 {
572                ref_time_limit,
573                ..self.limits.value()
574            }),
575            ..self
576        }
577    }
578
579    /// Sets the `proof_size_limit` part of the weight limit for the contract
580    /// instantiation.
581    #[inline]
582    pub fn proof_size_limit(self, proof_size_limit: u64) -> Self {
583        CreateBuilder {
584            limits: Set(LimitParamsV2 {
585                proof_size_limit,
586                ..self.limits.value()
587            }),
588            ..self
589        }
590    }
591
592    /// Sets the `storage_deposit_limit` for the contract instantiation.
593    #[inline]
594    pub fn storage_deposit_limit(self, storage_deposit_limit: U256) -> Self {
595        CreateBuilder {
596            limits: Set(LimitParamsV2 {
597                storage_deposit_limit: Some(storage_deposit_limit),
598                ..self.limits.value()
599            }),
600            ..self
601        }
602    }
603}
604
605impl<E, ContractRef, Limits, Args, RetType, Abi>
606    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
607where
608    E: Environment,
609{
610    /// Sets the value transferred upon the execution of the call.
611    #[inline]
612    pub fn endowment(
613        self,
614        endowment: U256,
615    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
616        CreateBuilder {
617            code_hash: self.code_hash,
618            limits: self.limits,
619            endowment,
620            exec_input: self.exec_input,
621            salt: self.salt,
622            return_type: self.return_type,
623            _phantom: Default::default(),
624        }
625    }
626}
627
628impl<E, ContractRef, Limits, RetType, Abi>
629    CreateBuilder<
630        E,
631        ContractRef,
632        Limits,
633        Unset<ExecutionInput<EmptyArgumentList<Abi>, Abi>>,
634        RetType,
635        Abi,
636    >
637where
638    E: Environment,
639{
640    /// Sets the value transferred upon the execution of the call.
641    #[inline]
642    pub fn exec_input<Args>(
643        self,
644        exec_input: ExecutionInput<Args, Abi>,
645    ) -> CreateBuilder<E, ContractRef, Limits, Set<ExecutionInput<Args, Abi>>, RetType, Abi>
646    {
647        CreateBuilder {
648            code_hash: self.code_hash,
649            limits: self.limits,
650            endowment: self.endowment,
651            exec_input: Set(exec_input),
652            salt: self.salt,
653            return_type: self.return_type,
654            _phantom: Default::default(),
655        }
656    }
657}
658
659impl<E, ContractRef, Limits, Args, RetType, Abi>
660    CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi>
661where
662    E: Environment,
663{
664    /// Sets the salt used for the execution of the call.
665    #[inline]
666    pub fn salt_bytes(
667        self,
668        salt: Option<[u8; 32]>,
669    ) -> CreateBuilder<E, ContractRef, Limits, Args, RetType, Abi> {
670        CreateBuilder {
671            code_hash: self.code_hash,
672            limits: self.limits,
673            endowment: self.endowment,
674            exec_input: self.exec_input,
675            salt,
676            return_type: self.return_type,
677            _phantom: Default::default(),
678        }
679    }
680}
681
682impl<E, ContractRef, Limits, Args, Abi>
683    CreateBuilder<E, ContractRef, Limits, Args, Unset<ReturnType<()>>, Abi>
684where
685    E: Environment,
686{
687    /// Sets the type of the returned value upon the execution of the constructor.
688    ///
689    /// # Note
690    ///
691    /// Constructors are not able to return arbitrary values. Instead, a successful call
692    /// to a constructor returns the address at which the contract was instantiated.
693    ///
694    /// Therefore this must always be a reference (i.e. `ContractRef`) to the contract
695    /// you're trying to instantiate.
696    #[inline]
697    pub fn returns<R>(
698        self,
699    ) -> CreateBuilder<E, ContractRef, Limits, Args, Set<ReturnType<R>>, Abi>
700    where
701        ContractRef: FromAddr,
702        R: ConstructorReturnType<ContractRef, Abi>,
703    {
704        CreateBuilder {
705            code_hash: self.code_hash,
706            limits: self.limits,
707            endowment: self.endowment,
708            exec_input: self.exec_input,
709            salt: self.salt,
710            return_type: Set(Default::default()),
711            _phantom: Default::default(),
712        }
713    }
714}
715
716impl<E, ContractRef, Limits, Args, RetType, Abi>
717    CreateBuilder<
718        E,
719        ContractRef,
720        Set<Limits>,
721        Set<ExecutionInput<Args, Abi>>,
722        Set<ReturnType<RetType>>,
723        Abi,
724    >
725where
726    E: Environment,
727{
728    /// Finalizes the `CreateBuilder`, allowing it to instantiate a contract.
729    #[inline]
730    pub fn params(self) -> CreateParams<E, ContractRef, Limits, Args, RetType, Abi> {
731        CreateParams {
732            code_hash: self.code_hash,
733            limits: self.limits.value(),
734            endowment: self.endowment,
735            exec_input: self.exec_input.value(),
736            salt_bytes: self.salt,
737            _return_type: Default::default(),
738            _phantom: Default::default(),
739        }
740    }
741}
742
743impl<E, ContractRef, Args, RetType, Abi>
744    CreateBuilder<
745        E,
746        ContractRef,
747        Set<LimitParamsV2>,
748        Set<ExecutionInput<Args, Abi>>,
749        Set<ReturnType<RetType>>,
750        Abi,
751    >
752where
753    E: Environment,
754    ContractRef: FromAddr + crate::ContractReverseReference,
755    <ContractRef as crate::ContractReverseReference>::Type:
756        crate::reflect::ContractConstructorDecoder,
757    <ContractRef as crate::ContractReverseReference>::Type:
758        crate::reflect::ContractMessageDecoder,
759    Args: AbiEncodeWith<Abi>,
760    RetType: ConstructorReturnType<ContractRef, Abi>,
761{
762    /// todo check comment
763    /// Instantiates the contract and returns its account ID back to the caller.
764    ///
765    /// # Panics
766    ///
767    /// This method panics if it encounters an [`ink::env::Error`][`crate::Error`] or an
768    /// [`ink::primitives::LangError`][`ink_primitives::LangError`]. If you want to handle
769    /// those use the [`try_instantiate`][`CreateBuilder::try_instantiate`] method
770    /// instead.
771    #[inline]
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    pub fn try_instantiate(
788        self,
789    ) -> Result<
790        ink_primitives::ConstructorResult<
791            <RetType as ConstructorReturnType<ContractRef, Abi>>::Output,
792        >,
793        Error,
794    > {
795        self.params().try_instantiate()
796    }
797}