use frame_support::{traits::fungible::Inspect, weights::Weight};
use pallet_contracts::Code;
use pallet_contracts_uapi::ReturnFlags;
use parity_scale_codec::Decode;
use sp_runtime::traits::Hash;
type ContractBalanceOf<T> = <<T as pallet_contracts::Config>::Currency as Inspect<
<T as frame_system::Config>::AccountId,
>>::Balance;
pub fn load_wasm_module<T>(
fixture_name: &str,
) -> std::io::Result<(Vec<u8>, <T::Hashing as Hash>::Output)>
where
T: frame_system::Config,
{
let fixture_path = ["../ink-contracts/", fixture_name, ".wasm"].concat();
let wasm_binary = std::fs::read(fixture_path)?;
let code_hash = T::Hashing::hash(&wasm_binary);
Ok((wasm_binary, code_hash))
}
pub fn deploy_wasm_contract<T: pallet_contracts::Config>(
contract_name: &str,
origin: T::AccountId,
value: ContractBalanceOf<T>,
gas_limit: Weight,
storage_deposit_limit: Option<ContractBalanceOf<T>>,
data: Vec<u8>,
) -> (T::AccountId, <T::Hashing as Hash>::Output) {
let (code, hash) = load_wasm_module::<T>(contract_name).unwrap();
let outcome = pallet_contracts::Pallet::<T>::bare_instantiate(
origin,
value,
gas_limit,
storage_deposit_limit,
Code::Upload(code),
data,
vec![],
pallet_contracts::DebugInfo::Skip,
pallet_contracts::CollectEvents::Skip,
);
let result = outcome.result.unwrap();
assert!(
!result.result.did_revert(),
"deploy_contract: reverted - {:?}",
result
);
(result.account_id, hash)
}
pub fn call_wasm_contract_method<T: pallet_contracts::Config, V: Decode>(
origin: T::AccountId,
dest: T::AccountId,
value: ContractBalanceOf<T>,
gas_limit: Weight,
storage_deposit_limit: Option<ContractBalanceOf<T>>,
data: Vec<u8>,
debug: bool,
) -> (V, ReturnFlags, Weight) {
let outcome = pallet_contracts::Pallet::<T>::bare_call(
origin,
dest,
value,
gas_limit,
storage_deposit_limit,
data,
pallet_contracts::DebugInfo::Skip,
pallet_contracts::CollectEvents::Skip,
pallet_contracts::Determinism::Enforced,
);
if debug {
println!(
"Contract debug buffer - {:?}",
String::from_utf8(outcome.debug_message.clone())
);
println!("Contract outcome - {outcome:?}");
}
let res = outcome.result.unwrap();
assert!(!res.did_revert(), "Contract reverted!");
let value = Result::<V, ()>::decode(&mut res.data.as_ref())
.expect("decoding failed")
.expect("ink! lang error");
(value, res.flags, outcome.gas_consumed)
}