Manual deployment
Let's manually build a smart contract that leverages Inco's random number generator in order to generate a random card using our external general message passing (GMP). For this tutorial we recommend having two different browser windows open with Metamask plugin installed on each.
Contract on Inco (A)
This boilerplate contract has two functions necessary for the initial "setup" that need to be called one after another. One is initialize(uint32, address, address) which takes in:
ChainID of target chain (84532 in case of Base Sepolia)
iexRouter address for Inco (0x015b8be6946ee593Ee2230E56221Db9cEE22aC20)
caller_contract, the address that is allowed to call the contract functions through the bridge (retreived by calling getICA() on the target contract)
Please refer to Cross-Chain gateways section to find your target chain router address and chainID.
InterchainAccountRouter | InterchainExecuteRouter | InterchainQueryRouter | Domain/ChainID | |
---|---|---|---|---|
Inco Gentry | 0x86A5337E029B32BA1d34e89Ff9A96667583C7b4B | 0x015b8be6946ee593Ee2230E56221Db9cEE22aC20 | 0xFD8992F4a09519d03071354683435c196c4b254c | 9090 |
Base Sepolia | 0x7867F458DBF31D9D9F7B1B758ea3847C3f7345fd | 0xAC4fAb4c9E99606d255EB87cFAfAd4587801f743 | 0x24303e65069756C8A9ae73E5567d9B59176B7d75 | 84532 |
Edgeless | 0xEA7E5a8Cb8741250326532b72c1bA05D067F8A61 | 0xc5F722b899dee3F01fC530f10664043aF0B927B2 | 0xC0F6aa9bA0f833d6a9e2c3AC2D3D7973Ba2984F2 | 202 |
The second function getICA(address) will return a contract address that belongs to the bridge, and it's the contract that will call our custom bridge functions on our behalf.
Let's continue writing the rest of our smart contract on Inco. We just need to write two custom functions, one for generating a random card, and the other for reveling user's card:
Contract on target chain (B)
Now we need to write a second contract which will be deployed on your target chain that isn't Inco. The boilerplate code looks very similar to previous one:
In order to interact with our Inco contract, we use Interchain Execution Router to call our code on Inco by passing arguments like chainID, contract address containing our hidden logic on Inco, rlp encoded function signature with arguments that will be passed in as calldata, and an rlp encoded func signature of a callback function that will be invoked containing our return values (in our case it's cardReceive(uint256, uint8) function).
Deployment
When deploying both contracts on their respective chains, we first initialize each contract manually, starting with contract on Inco, since we need to pass it's address to the contract on Base.
For the left window A we use the following highlighted values from the table to initialize the contract on Inco:
InterchainAccountRouter | InterchainExecuteRouter | InterchainQueryRouter | Domain/ChainID | |
---|---|---|---|---|
Inco Gentry | 0x86A5337E029B32BA1d34e89Ff9A96667583C7b4B | 0x015b8be6946ee593Ee2230E56221Db9cEE22aC20 | 0xFD8992F4a09519d03071354683435c196c4b254c | 9090 |
Base Sepolia | 0x7867F458DBF31D9D9F7B1B758ea3847C3f7345fd | 0xAC4fAb4c9E99606d255EB87cFAfAd4587801f743 | 0x24303e65069756C8A9ae73E5567d9B59176B7d75 | 84532 |
For the right window B we use the following values instead to initialize the contract on Base:
InterchainAccountRouter | InterchainExecuteRouter | InterchainQueryRouter | Domain/ChainID | |
---|---|---|---|---|
Inco Gentry | 0x86A5337E029B32BA1d34e89Ff9A96667583C7b4B | 0x015b8be6946ee593Ee2230E56221Db9cEE22aC20 | 0xFD8992F4a09519d03071354683435c196c4b254c | 9090 |
Base Sepolia | 0x7867F458DBF31D9D9F7B1B758ea3847C3f7345fd | 0xAC4fAb4c9E99606d255EB87cFAfAd4587801f743 | 0x24303e65069756C8A9ae73E5567d9B59176B7d75 | 84532 |
Please refer to Cross-Chain gateways table to find correct DestinationDomain as well as iexRouter address.
Next we call getICA() followed by setCallerContract() on Inco to get the caller contract address that will be allowed to call to it, and for the one on base we just set the same value we used for iexRouter:
Now both bridge contracts should be able to talk to each other.
Using the bridge
In order to use the bridge, we simply interact with the contract deployed on Base. To check if everything works correctly, we first call GetCard(address) function in order to generate a card (address we pass as argument doesn't matter), then we call CardView(address) with the same address in order to reveal the card stored on Inco:
And now in order to reveal the card that we have just generated, we call CardView() function, passing the same ethereum address as argument:
And that is it for now. Hope you find this tutorial helpful, and happy bridging!
Last updated