referrerpolicy=no-referrer-when-downgrade

pallet_contracts/
address.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Functions that deal with address derivation.
19
20use crate::{CodeHash, Config};
21use codec::{Decode, Encode};
22use sp_runtime::traits::{Hash, TrailingZeroInput};
23
24/// Provides the contract address generation method.
25///
26/// See [`DefaultAddressGenerator`] for the default implementation.
27///
28/// # Note for implementors
29///
30/// 1. Make sure that there are no collisions, different inputs never lead to the same output.
31/// 2. Make sure that the same inputs lead to the same output.
32pub trait AddressGenerator<T: Config> {
33	/// The address of a contract based on the given instantiate parameters.
34	///
35	/// Changing the formular for an already deployed chain is fine as long as no collisions
36	/// with the old formular. Changes only affect existing contracts.
37	fn contract_address(
38		deploying_address: &T::AccountId,
39		code_hash: &CodeHash<T>,
40		input_data: &[u8],
41		salt: &[u8],
42	) -> T::AccountId;
43}
44
45/// Default address generator.
46///
47/// This is the default address generator used by contract instantiation. Its result
48/// is only dependent on its inputs. It can therefore be used to reliably predict the
49/// address of a contract. This is akin to the formula of eth's CREATE2 opcode. There
50/// is no CREATE equivalent because CREATE2 is strictly more powerful.
51/// Formula:
52/// `hash("contract_addr_v1" ++ deploying_address ++ code_hash ++ input_data ++ salt)`
53pub struct DefaultAddressGenerator;
54
55impl<T: Config> AddressGenerator<T> for DefaultAddressGenerator {
56	/// Formula: `hash("contract_addr_v1" ++ deploying_address ++ code_hash ++ input_data ++ salt)`
57	fn contract_address(
58		deploying_address: &T::AccountId,
59		code_hash: &CodeHash<T>,
60		input_data: &[u8],
61		salt: &[u8],
62	) -> T::AccountId {
63		let entropy = (b"contract_addr_v1", deploying_address, code_hash, input_data, salt)
64			.using_encoded(T::Hashing::hash);
65		Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
66			.expect("infinite length input; no invalid inputs for type; qed")
67	}
68}