My understanding is that fundamentally IBC is the problem of allowing main-chain full nodes to prove to main-chain light clients (who also operate side-chain full nodes) that a transaction happened, it was valid, and it's irreversible. I don't think
contract1 can directly send a transaction to
contract2 on a different chain; the communication of proofs is done in a p2p manner between nodes and through block headers, and the actual implementations can vary.
For instance, there can be a multisig account shared among BPs, say
eosio.sidechain1 on the main-chain, and the protocol can be as follows (from the perspective of the side-chain operating nodes, which are main-chain light clients):
If you send EOS to
eosio.sidechain1 on the main-chain and prove that you did so, you'll have side-chain tokens released on our side-chain and we'll communicate proof of doing so. However, because we only operate light-clients and don't download all the blocks on the main-chain, you'll have to prove this to us using only block headers.
Because proofs have to be light and side-chain operators only have block headers from main-chain, to prove that a particular action was indeed included in the main-chain, you'd need to communicate several merkle proofs. Your proof may include: the action itself, the "action path" that proves the ordering of the actions given the actions Merkle tree and Merkle root from block headers, the block in which your action was included, and the "block path" which can be used in conjuction with the block Merkle tree to prove that a block is valid and irreversible.
Once this is done, the light clients have proof that a transaction happened and they can release the side-chain tokens on their side-chain. Once they do that, they can generate proof to main-chain nodes that this happened and the user has their tokens on the side-chain. If they don't, the main-chain BPs can just return the EOS tokens to the user.
So the process in this case would be:
- User sends EOS to multisig
- User or BPs or non-producing nodes send proof to side-chain that the action happened and is irreversible;
Side-chains confirm proof and either:
a. Release tokens for the user on the side-chain and prove that they did so to main-chain, in which case everything went fine; or
b. don't release tokens for the user on the side-chain, in which case
eosio.sidechain1 returns the tokens to the user e.g. multisig transaction from BPs or time-lock smart contract
Note that this is just an example of how this could work; I don't think implementation-specific details have been released, and IBC is not yet ready as far as I'm aware. Implementations may use contracts for e.g. time-locking mechanism, but I think EOSIO should be able to implement IBC natively without IBC-specific contracts. Further, using this type of mechanism, the process can be abstracted from both users and developers; e.g. someone may just say "send tokens to contract X on side-chain Y" and although an intermediate transaction to a non-contract account or to a contract may take place, this may be hidden from users/devs.
Please correct me if I'm wrong; the only docs I've seen on IBC have been the whitepaper and Dan's post on IBC.