diff --git a/piecrust/CHANGELOG.md b/piecrust/CHANGELOG.md index 943c46ad..26e03854 100644 --- a/piecrust/CHANGELOG.md +++ b/piecrust/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added `deploy_raw` method for serialized constructor arguments [#371] + ### Changed - Make each event byte cost the same as a storage byte [#359] @@ -441,6 +445,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +[#371]: https://github.com/dusk-network/piecrust/issues/371 [#359]: https://github.com/dusk-network/piecrust/issues/359 [#357]: https://github.com/dusk-network/piecrust/issues/357 [#353]: https://github.com/dusk-network/piecrust/issues/353 diff --git a/piecrust/src/session.rs b/piecrust/src/session.rs index b9e32137..79d77534 100644 --- a/piecrust/src/session.rs +++ b/piecrust/src/session.rs @@ -222,16 +222,7 @@ impl Session { A: 'a + for<'b> Serialize>, D: Into>, { - let mut deploy_data = deploy_data.into(); - - match deploy_data.contract_id { - Some(_) => (), - _ => { - let hash = blake3::hash(bytecode); - deploy_data.contract_id = - Some(ContractId::from_bytes(hash.into())); - } - }; + let deploy_data = deploy_data.into(); let mut constructor_arg = None; if let Some(arg) = deploy_data.constructor_arg { @@ -246,15 +237,53 @@ impl Session { constructor_arg = Some(self.inner.buffer[0..pos].to_vec()); } - let contract_id = deploy_data.contract_id.unwrap(); - self.do_deploy( - contract_id, + self.deploy_raw( + deploy_data.contract_id, bytecode, constructor_arg, deploy_data .owner .expect("Owner must be specified when deploying a contract"), gas_limit, + ) + } + + /// Deploy a contract, returning its [`ContractId`]. If ID is not provided, + /// it is computed using a `blake3` hash of the `bytecode`. Contracts using + /// the `memory64` proposal are accepted in just the same way as 32-bit + /// contracts, and their handling is totally transparent. + /// + /// Since a deployment may execute some contract initialization code, that + /// code will be metered and executed with the given `gas_limit`. + /// + /// # Errors + /// It is possible that a collision between contract IDs occurs, even for + /// different contract IDs. This is due to the fact that all contracts have + /// to fit into a sparse merkle tree with `2^32` positions, and as such + /// a 256-bit number has to be mapped into a 32-bit number. + /// + /// If such a collision occurs, [`PersistenceError`] will be returned. + /// + /// [`ContractId`]: ContractId + /// [`PersistenceError`]: PersistenceError + pub fn deploy_raw( + &mut self, + contract_id: Option, + bytecode: &[u8], + constructor_arg: Option>, + owner: Vec, + gas_limit: u64, + ) -> Result { + let contract_id = contract_id.unwrap_or({ + let hash = blake3::hash(bytecode); + ContractId::from_bytes(hash.into()) + }); + self.do_deploy( + contract_id, + bytecode, + constructor_arg, + owner, + gas_limit, )?; Ok(contract_id)