CosmWasm / cosmwasm

Framework for building smart contracts in Wasm for the Cosmos SDK
https://www.cosmwasm.com/
Apache License 2.0
1.07k stars 335 forks source link

Allow to query ContractInfo for a contract #1082

Closed ethanfrey closed 3 years ago

ethanfrey commented 3 years ago

This is based on ideas from https://github.com/CosmWasm/wasmd/issues/584 which have come up in Discord several times from a number of different groups. Basically, people want to:

  1. Check if an address is a contract or an external account
  2. Check what code_id is behind a contract (maybe we only allow unmodified cw20-base for example)
  3. Check on the admin / migratability of a contract

We may also want to allow to see if the contract (actually the linked code_id) is pinned per https://github.com/CosmWasm/wasmd/issues/596

We can model it on the existing grpc client response, particularly the ContractInfo type.

Query:

pub enum WasmQuery {
    Smart { ... },
    Raw { ... },
    ContractInfo {
        contract_addr: String,
    }
}

Response:

pub struct ContractInfoResponse {
   // these seem essential
    pub code_id: u64,
    pub creator: String,
    pub admin: Option<String>,

    // this would be useful info, but maybe not easily available?
    pub pinned: bool,

    // TODO: is this covered by other IBC queries already?
    pub ibc_port: Option<String>,

    // also on gRPC return value, but maybe we drop them?
    pub label: String,
    pub created: AbsoluteTxPosition,
    pub extension: Option<Any>,
}

I would love feedback from @alpe and @webmaster128 on the API design here. It is a non-breaking addition to the API, and quite useful functionality. We should just review what data and in what format.

alpe commented 3 years ago
pub pinned: bool,

Is stored in a second index and available

pub ibc_port: Option<String>,

Is in the IBC queries already

pub created: AbsoluteTxPosition,

We are not exposing AbsoluteTxPosition to clients and should not do it here as well, IMHO

pub extension: Option<Any>,

I am not sure if we should support this. The extension would be chain agnostic and has impact on contract portability. It could lead to tight coupling with the persistence object. Custom queries may a be a cleaner way to get the information (when supported) and contracts won't have to deal with protobuf.

ethanfrey commented 3 years ago

Taking in Alex's feedback, maybe we end up with:

pub struct ContractInfoResponse {
    pub code_id: u64,
    pub creator: String,
    pub admin: Option<String>,
    pub pinned: bool,
    /// block this was created at
    pub created_height: u64,

    pub ibc_port: Option<String>,
}

I looked up the IBC query and it only returns the PortID for the current contract. Not for another contract. Not sure if this would be useful until loopback ibc connections are fully enabled (they exist in theory), but may already be interesting as None/Some(_) info. eg. "a token contract that doesn't want to be passed over IBC and thus disallows transferring tokens to any address with ibc_port set"