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}