Account A deploys Contract A. Account A then calls Contract B function register, passing the address of Contract A. Is it possible to prove that Account A deployed Contract A from within the register function of Contract B without implementing some kind of proof of deployment function in Contract A?

Contract A

Deployed by Account A. The contract contains no record of Account A in storage.

Contract B

Account A then calls this function passing the Contract A address.

pub fn register(
    &mut self,
    dapp_account: AccountId,
) -> Result<(), Error> {
    let caller = self.env().caller();

    // check that the dapp_account is a contract
    if !self.env().is_contract(&dapp_account) {
         return Err(Error::InvalidContract);

    // prove that the caller deployed `dapp_account`
    // ?? check the contracts.instantiateWithCode extrinsic plus a merkle trie proof of the block inclusion on-chain?

I'm assuming this would require the contract instantiate extrinsic, a proof of the extrinsic being in a block, and a proof of the block being on-chain.

1 Answer 1


In the contract_pallet there is a mapping between the code hash and the owner of the contract. (see the code).

pub(crate) type OwnerInfoOf<T: Config> = StorageMap<_, Identity, CodeHash<T>, OwnerInfo<T>>;

But I see that what you have is not the hash, is the account ID of the contract, then you will have to query first the ContractInfoOf which is a mapping between the contract accountId and the contract info (which includes the code hash)

pub(crate) type ContractInfoOf<T: Config> =
    StorageMap<_, Twox64Concat, T::AccountId, ContractInfo<T>>;

Is possible to interact with the runtime from a ink! smart contract with chain extensions, see this previous StackExchange answers that has some examples of how to achieve that:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.