diff --git a/soroban-sdk/src/constructor_args.rs b/soroban-sdk/src/constructor_args.rs new file mode 100644 index 00000000..e4935945 --- /dev/null +++ b/soroban-sdk/src/constructor_args.rs @@ -0,0 +1,32 @@ +use crate::{Env, IntoVal, Val, Vec}; + +pub trait ConstructorArgs: IntoVal> {} + +impl ConstructorArgs for Vec {} + +macro_rules! impl_constructor_args_for_tuple { + ( $($typ:ident $idx:tt)* ) => { + impl<$($typ),*> ConstructorArgs for ($($typ,)*) + where + $($typ: IntoVal),* + { + } + }; +} + +// 0 topics +impl ConstructorArgs for () {} +// 1-13 topics +impl_constructor_args_for_tuple! { T0 0 } +impl_constructor_args_for_tuple! { T0 0 T1 1 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 } +impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 } diff --git a/soroban-sdk/src/deploy.rs b/soroban-sdk/src/deploy.rs index 640b9399..b47d33ed 100644 --- a/soroban-sdk/src/deploy.rs +++ b/soroban-sdk/src/deploy.rs @@ -27,7 +27,7 @@ //! // Deployed contract address is deterministic and can be accessed //! // before deploying the contract. //! let _ = deployer.deployed_address(); -//! let contract_address = deployer.deploy(wasm_hash); +//! let contract_address = deployer.deploy_v2(wasm_hash, ()); //! } //! } //! #[test] @@ -61,8 +61,10 @@ //! // Deployed contract address is deterministic and can be accessed //! // before deploying the contract. //! let _ = deployer.deployed_address(); -//! let contract_address = deployer.deploy_with_constructor( -//! wasm_hash, (1_u32, 2_i64).into_val(&env)); +//! let contract_address = deployer.deploy_v2( +//! wasm_hash, +//! (1_u32, 2_i64), +//! ); //! } //! } //! #[test] @@ -82,8 +84,8 @@ //! ``` use crate::{ - env::internal::Env as _, unwrap::UnwrapInfallible, Address, Bytes, BytesN, Env, IntoVal, Val, - Vec, + env::internal::Env as _, unwrap::UnwrapInfallible, Address, Bytes, BytesN, ConstructorArgs, + Env, IntoVal, }; /// Deployer provides access to deploying contracts. @@ -258,6 +260,7 @@ impl DeployerWithAddress { /// and provided salt. /// /// Returns the deployed contract's address. + #[deprecated(note = "use deploy_v2")] pub fn deploy(&self, wasm_hash: impl IntoVal>) -> Address { let env = &self.env; let address_obj = env @@ -272,24 +275,29 @@ impl DeployerWithAddress { /// Deploy a contract that uses Wasm executable with provided hash. /// - /// `constructor_args` will be passed to the contract's constructor. + /// The constructor args will be passed to the contract's constructor. Pass + /// `()` for contract's with no constructor or a constructor with zero + /// arguments. /// /// The address of the deployed contract is defined by the deployer address /// and provided salt. /// /// Returns the deployed contract's address. - pub fn deploy_with_constructor( + pub fn deploy_v2( &self, wasm_hash: impl IntoVal>, - constructor_args: Vec, - ) -> Address { + constructor_args: A, + ) -> Address + where + A: ConstructorArgs, + { let env = &self.env; let address_obj = env .create_contract_with_constructor( self.address.to_object(), wasm_hash.into_val(env).to_object(), self.salt.to_object(), - constructor_args.to_object(), + constructor_args.into_val(env).to_object(), ) .unwrap_infallible(); unsafe { Address::unchecked_new(env.clone(), address_obj) } diff --git a/soroban-sdk/src/env.rs b/soroban-sdk/src/env.rs index 1d04b3a5..067211ab 100644 --- a/soroban-sdk/src/env.rs +++ b/soroban-sdk/src/env.rs @@ -453,11 +453,11 @@ impl Env { use crate::{ auth, testutils::{ - budget::Budget, Address as _, AuthSnapshot, AuthorizedInvocation, ConstructorArgs, - ContractFunctionSet, EventsSnapshot, Generators, Ledger as _, MockAuth, MockAuthContract, - Register, Snapshot, StellarAssetContract, StellarAssetIssuer, + budget::Budget, Address as _, AuthSnapshot, AuthorizedInvocation, ContractFunctionSet, + EventsSnapshot, Generators, Ledger as _, MockAuth, MockAuthContract, Register, Snapshot, + StellarAssetContract, StellarAssetIssuer, }, - Bytes, BytesN, + Bytes, BytesN, ConstructorArgs, }; #[cfg(any(test, feature = "testutils"))] use core::{cell::RefCell, cell::RefMut}; @@ -588,7 +588,7 @@ impl Env { /// contract id passed in. /// /// If you need to specify the address the contract should be registered at, - /// use [`register_at`]. + /// use [`Env::register_at`]. /// /// ### Examples /// Register a contract defined in the current crate, by specifying the type diff --git a/soroban-sdk/src/lib.rs b/soroban-sdk/src/lib.rs index a4b8aa5c..95207d7a 100644 --- a/soroban-sdk/src/lib.rs +++ b/soroban-sdk/src/lib.rs @@ -813,6 +813,9 @@ mod string; pub use string::String; mod tuple; +mod constructor_args; +pub use constructor_args::ConstructorArgs; + pub mod xdr; pub mod testutils; diff --git a/soroban-sdk/src/testutils.rs b/soroban-sdk/src/testutils.rs index 8aa6e0c3..55ba0b22 100644 --- a/soroban-sdk/src/testutils.rs +++ b/soroban-sdk/src/testutils.rs @@ -18,7 +18,7 @@ use soroban_env_host::TryIntoVal; pub mod storage; -use crate::{xdr, Env, IntoVal, Val, Vec}; +use crate::{xdr, ConstructorArgs, Env, Val, Vec}; use soroban_ledger_snapshot::LedgerSnapshot; pub use crate::env::EnvTestConfig; @@ -53,37 +53,6 @@ impl<'w> Register for &'w [u8] { } } -pub trait ConstructorArgs: IntoVal> {} - -impl ConstructorArgs for Vec {} - -macro_rules! impl_constructor_args_for_tuple { - ( $($typ:ident $idx:tt)* ) => { - impl<$($typ),*> ConstructorArgs for ($($typ,)*) - where - $($typ: IntoVal),* - { - } - }; -} - -// 0 topics -impl ConstructorArgs for () {} -// 1-13 topics -impl_constructor_args_for_tuple! { T0 0 } -impl_constructor_args_for_tuple! { T0 0 T1 1 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 } -impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 } - #[derive(Default, Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "snake_case")] pub struct Snapshot {