github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/IBC.md (about)

     1  # IBC specification
     2  
     3  This documents how CosmWasm contracts are expected to interact with IBC.
     4  
     5  ## General Concepts
     6  
     7  **IBC Enabled** - when instantiating a contract, we detect if it supports IBC messages.
     8    We require "feature flags" in the contract/vm handshake to ensure compatibility
     9    for features like staking or chain-specific extensions. IBC functionality will require
    10    another "feature flag", and the list of "enabled features" can be returned to the `x/wasm`
    11    module to control conditional IBC behavior.
    12    
    13    If this feature is enabled, it is considered "IBC Enabled", and that info will
    14    be stored in the ContractInfo. (For mock, we assume all contracts are IBC enabled)
    15    
    16  Also, please read the [IBC Docs](https://docs.cosmos.network/master/ibc/overview.html)
    17  for detailed descriptions of the terms *Port*, *Client*, *Connection*,
    18  and *Channel*
    19    
    20  ## Overview
    21  
    22  We use "One Port per Contract", which is the most straight-forward mapping, treating each contract 
    23  like a module. It does lead to very long portIDs however. Pay special attention to both the Channel establishment 
    24  (which should be compatible with standard ICS20 modules without changes on their part), as well
    25  as how contracts can properly identify their counterparty.
    26  
    27  (We considered on port for the `x/wasm` module and multiplexing on it, but [dismissed that idea](#rejected-ideas))
    28  
    29  * Upon `Instantiate`, if a contract is *IBC Enabled*, we dynamically 
    30    bind a port for this contract. The port name is `wasm.<contract address>`,
    31    eg. `wasm.cosmos1hmdudppzceg27qsuq707tjg8rkgj7g5hnvnw29`
    32  * If a *Channel* is being established with a registered `wasm.xyz` port,
    33    the `x/wasm.Keeper` will handle this and call into the appropriate
    34    contract to determine supported protocol versions during the
    35    [`ChanOpenTry` and `ChanOpenAck` phases](https://docs.cosmos.network/master/ibc/overview.html#channels).
    36    (See [Channel Handshake Version Negotiation](https://docs.cosmos.network/master/ibc/custom.html#channel-handshake-version-negotiation))
    37  * Both the *Port* and the *Channel* are fully owned by one contract.
    38  * `x/wasm` will allow both *ORDERED* and *UNORDERED* channels and pass that mode
    39    down to the contract in `OnChanOpenTry`, so the contract can decide if it accepts
    40    the mode. We will recommend the contract developers stick with *ORDERED* channels
    41    for custom protocols unless they can reason about async packet timing.
    42  * When sending a packet, the CosmWasm contract must specify the local *ChannelID*.
    43    As there is a unique *PortID* per contract, that is filled in by `x/wasm`
    44    to produce the globally unique `(PortID, ChannelID)`
    45  * When receiving a Packet (or Ack or Timeout), the contracts receives the local
    46    *ChannelID* it came from, as well as the packet that was sent by the counterparty.
    47  * When receiving an Ack or Timeout packet, the contract also receives the
    48    original packet that it sent earlier.
    49  * We do not support multihop packets in this model (they are rejected by `x/wasm`).
    50    They are currently not fully specified nor implemented in IBC 1.0, so let us
    51    simplify our model until this is well established
    52  
    53  ## Workflow
    54  
    55  Establishing *Clients* and *Connections* is out of the scope of this
    56  module and must be created by the same means as for `ibc-transfer`
    57  (via the [go cli](https://github.com/fibonacci-chain/fbc/libs/relayer) or better [ts-relayer](https://github.com/confio/ts-relayer)).
    58  `x/wasm` will bind a unique *Port* for each "IBC Enabled" contract.
    59  
    60  For mocks, all the Packet Handling and Channel Lifecycle Hooks are routed 
    61  to some Golang stub handler, but containing the contract address, so we
    62  can perform contract-specific actions for each packet. In a real setting,
    63  we route to the contract that owns the port/channel and call one of it's various
    64  entry points.
    65  
    66  Please refer to the CosmWasm repo for all 
    67  [details on the  IBC API from the point of view of a CosmWasm contract](https://github.com/CosmWasm/cosmwasm/blob/main/IBC.md).
    68  
    69  ## Future Ideas
    70  
    71  Here are some ideas we may add in the future
    72  
    73  ### Dynamic Ports and Channels
    74  
    75  * multiple ports per contract
    76  * elastic ports that can be assigned to different contracts
    77  * transfer of channels to another contract
    78  
    79  This is inspired by the Agoric design, but also adds considerable complexity to both the `x/wasm`
    80  implementation as well as the correctness reasoning of any given contract. This will not be
    81  available in the first version of our "IBC Enabled contracts", but we can consider it for later,
    82  if there are concrete user cases that would significantly benefit from this added complexity. 
    83  
    84  ### Add multihop support
    85  
    86  Once the ICS and IBC specs fully establish how multihop packets work, we should add support for that.
    87  Both on setting up the routes with OpenChannel, as well as acting as an intermediate relayer (if that is possible)
    88  
    89  ## Rejected Ideas
    90    
    91  ### One Port per Module
    92  
    93  We decided on "one port per contract", especially after the IBC team raised
    94  the max length on port names to allow `wasm-<bech32 address>` to be a valid port.
    95  Here are the arguments for "one port for x/wasm" vs "one port per contract". Here 
    96  was an alternate proposal:
    97  
    98  In this approach, the `x/wasm` module just binds one port to handle all
    99  modules. This can be well defined name like `wasm`. Since we always
   100  have `(ChannelID, PortID)` for routing messages, we can reuse one port
   101  for all contracts as long as we have a clear way to map the `ChannelID`
   102  to a specific contract when it is being established.
   103  
   104  
   105  * On genesis we bind the port `wasm` for all communication with the `x/wasm`
   106    module.
   107  * The *Port* is fully owned by `x/wasm`
   108  * Each *Channel* is fully owned by one contract.
   109  * `x/wasm` only accepts *ORDERED Channels* for simplicity of contract
   110    correctness.
   111  
   112  To clarify:
   113  
   114  * When a *Channel* is being established with port `wasm`, the
   115    `x/wasm.Keeper` must be able to identify for which contract this
   116    is destined. **how to do so**??
   117    * One idea: the channel name must be the contract address. This means
   118      (`wasm`, `cosmos13d...`) will map to the given contract in the wasm module.
   119      The problem with this is that if two contracts from chainA want to
   120      connect to the same contracts on chainB, they will want to claim the
   121      same *ChannelID* and *PortID*. Not sure how to differentiate multiple
   122      parties in this way.
   123    * Other ideas: have a special field we send on `OnChanOpenInit` that
   124      specifies the destination contract, and allow any *ChannelID*.
   125      However, looking at [`OnChanOpenInit` function signature](https://docs.cosmos.network/master/ibc/custom.html#implement-ibcmodule-interface-and-callbacks),
   126      I don't see a place to put this extra info, without abusing the version field,
   127      which is a [specified field](https://docs.cosmos.network/master/ibc/custom.html#channel-handshake-version-negotiation):
   128      ```
   129      Versions must be strings but can implement any versioning structure. 
   130      If your application plans to have linear releases then semantic versioning is recommended.
   131      ... 
   132      Valid version selection includes selecting a compatible version identifier with a subset 
   133      of features supported by your application for that version.
   134      ...    
   135      ICS20 currently implements basic string matching with a
   136      single supported version.
   137      ```