Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update vibc-core-smart-contracts dependency #4

Merged
merged 8 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ node_modules

# solidity-coverage files
/coverage
/coverage.json
/coverage.json

# Foundry files
/out
/cache_forge
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "lib/vibc-core-smart-contracts"]
path = lib/vibc-core-smart-contracts
url = https://github.com/open-ibc/vibc-core-smart-contracts
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
48 changes: 32 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Template for IBC enabled Soldity contracts

This tutorial enables to send an IBC packet from an "Xcounter" contract on either OP or Base. The packet will ensure that a counter variable on either contract remains in sync.
This repo provides a starter project to build [IBC](https://github.com/cosmos/ibc) enabled Solidity contracts that connect rollups to one another Polymer Hub, through the [vIBC core contracts](https://github.com/open-ibc/vibc-core-smart-contracts).
tmsdkeys marked this conversation as resolved.
Show resolved Hide resolved

The repo is compatible with both Hardhat and Foundry development environments.

Find more information on building with (v)IBC and Polymer in the [Polymer documentation](https://docs.polymerlabs.org).

## Install dependencies

To use the quickstart tutorial, make sure that you have all dependencies installed.
To compile your contracts and start testing, make sure that you have all dependencies installed.

From the root directory run:
```bash
Expand Down Expand Up @@ -32,30 +36,33 @@ There's three types of scripts in the project:

- `deploy.js` and `deploy-config.js` allow you to deploy your application contract
- `create-channel.js` and `create-channel-config.js` creates a channel
- `send-packet.js` sends packets over an existing channel
- `send-packet.js` and `send-universal-packet.js` sends packets over an existing channel (custom or universal).
tmsdkeys marked this conversation as resolved.
Show resolved Hide resolved

For every script you'll find a field in the config.json!!

Make sure to update the config with the intended files before running one of the scripts like so:
```bash
npx hardhat run scripts/send-packet.js --network optimism
```

**NOTE** Make sure to align the `--network` flag value to be compatible with your config values either on optimism or base.

## Deploy
### Deploy

Run:
```bash
# format node scripts/deploy-config.js [source] [destination]
node scripts/deploy-config.js optimism base
# format node scripts/deploy-config.js [source] [destination] [universal-channel-bool]
node scripts/deploy-config.js optimism base true
```
for an application that will use a universal channel, or:
```bash
# or
node scripts/deploy-config.js optimism base false
```
for an application that uses custom channels.

To deploy instances of the contracts on optimism as the source and base as the destination chains. (You can also switch the order)

Also this script will take the output of the deployment and update the config file with all the relevant information.

Then run:
### Create a channel

In case you're using universal channels, you can skip this step and move on the sending packets.
tmsdkeys marked this conversation as resolved.
Show resolved Hide resolved

To create a custom channel, run:
```bash
node scripts/create-channel-config.js
```
Expand All @@ -66,8 +73,17 @@ Also this script will take the output of the channel creation and update the con

Check out the [channel tab in the explorer](https://explorer.prod.testnet.polymer.zone/channels) to find out if the correct channel-id's related to your contracts were updated in the config.

Finally run:
### Send packets
Finally Run:
```bash
npx hardhat run scripts/send-universal-packet.js --network optimism
```
to send a packet over a **universal channel**. You can pick either optimism or base to send the packet from.

Or run:
```bash
npx hardhat run scripts/send-packet.js --network optimism
```
to send a packet. You can pick either optimism or base to send the packet from.
to send a packet over a **custom channel**. You can pick either optimism or base to send the packet from.

**NOTE** Make sure to align the `--network` flag value to be compatible with your config values either on optimism or base.
45 changes: 22 additions & 23 deletions contracts/CustomChanIbcContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

pragma solidity ^0.8.9;

import '../lib/vibc-core-smart-contracts/contracts/Ibc.sol';
import '../lib/vibc-core-smart-contracts/contracts/IbcReceiver.sol';
import '../lib/vibc-core-smart-contracts/contracts/IbcDispatcher.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/Ibc.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/IbcReceiver.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/IbcDispatcher.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/ProofVerifier.sol';

contract CustomChanIbcContract is IbcReceiverBase, IbcReceiver {
// received packet as chain B
Expand All @@ -31,6 +32,10 @@ contract CustomChanIbcContract is IbcReceiverBase, IbcReceiver {
dispatcher = _dispatcher;
}

function getConnectedChannels() external view returns (ChannelMapping[] memory) {
return connectedChannels;
}

/**
* @dev Sends a packet with a greeting message over a specified channel.
* @param message The greeting message to be sent.
Expand Down Expand Up @@ -66,35 +71,33 @@ contract CustomChanIbcContract is IbcReceiverBase, IbcReceiver {
* @param proof not implemented for now
*/
function createChannel(
string calldata version,
CounterParty calldata local,
uint8 ordering,
bool feeEnabled,
string[] calldata connectionHops,
CounterParty calldata counterparty,
Proof calldata proof
Ics23Proof calldata proof
) external {

dispatcher.openIbcChannel(
IbcChannelReceiver(address(this)),
version,
local,
ChannelOrder(ordering),
feeEnabled,
connectionHops,
counterparty,
proof
);
}
}

function onOpenIbcChannel(
string calldata version,
ChannelOrder ordering,
bool feeEnabled,
string[] calldata connectionHops,
string calldata counterpartyPortId,
bytes32 counterpartyChannelId,
string calldata counterpartyVersion
) external onlyIbcDispatcher returns (string memory selectedVersion) {
if (bytes(counterpartyPortId).length <= 8) {
ChannelOrder,
bool,
string[] calldata,
CounterParty calldata counterparty
) external view onlyIbcDispatcher returns (string memory selectedVersion) {
if (bytes(counterparty.portId).length <= 8) {
revert invalidCounterPartyPortId();
}
/**
Expand All @@ -105,7 +108,7 @@ contract CustomChanIbcContract is IbcReceiverBase, IbcReceiver {
*/
bool foundVersion = false;
selectedVersion = keccak256(abi.encodePacked(version)) == keccak256(abi.encodePacked(''))
? counterpartyVersion
? counterparty.version
: version;
for (uint256 i = 0; i < supportedVersions.length; i++) {
if (keccak256(abi.encodePacked(selectedVersion)) == keccak256(abi.encodePacked(supportedVersions[i]))) {
Expand All @@ -115,9 +118,9 @@ contract CustomChanIbcContract is IbcReceiverBase, IbcReceiver {
}
require(foundVersion, 'Unsupported version');
// if counterpartyVersion is not empty, then it must be the same foundVersion
if (keccak256(abi.encodePacked(counterpartyVersion)) != keccak256(abi.encodePacked(''))) {
if (keccak256(abi.encodePacked(counterparty.version)) != keccak256(abi.encodePacked(''))) {
require(
keccak256(abi.encodePacked(counterpartyVersion)) == keccak256(abi.encodePacked(selectedVersion)),
keccak256(abi.encodePacked(counterparty.version)) == keccak256(abi.encodePacked(selectedVersion)),
'Version mismatch'
);
}
Expand Down Expand Up @@ -151,11 +154,7 @@ contract CustomChanIbcContract is IbcReceiverBase, IbcReceiver {
connectedChannels.push(channelMapping);
}

function onCloseIbcChannel(
bytes32 channelId,
string calldata counterpartyPortId,
bytes32 counterpartyChannelId
) external onlyIbcDispatcher {
function onCloseIbcChannel(bytes32 channelId, string calldata, bytes32) external onlyIbcDispatcher {
// logic to determin if the channel should be closed
bool channelFound = false;
for (uint256 i = 0; i < connectedChannels.length; i++) {
Expand Down
14 changes: 7 additions & 7 deletions contracts/UniversalChanIbcContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

pragma solidity ^0.8.9;

import '../lib/vibc-core-smart-contracts/contracts/Ibc.sol';
import '../lib/vibc-core-smart-contracts/contracts/IbcReceiver.sol';
import '../lib/vibc-core-smart-contracts/contracts/IbcDispatcher.sol';
import '../lib/vibc-core-smart-contracts/contracts/IbcMiddleware.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/Ibc.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/IbcReceiver.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/IbcDispatcher.sol';
import '@open-ibc/vibc-core-smart-contracts/contracts/IbcMiddleware.sol';

contract UniversalChanIbcContract is IbcMwUser, IbcUniversalPacketReceiver {
struct UcPacketWithChannel {
Expand Down Expand Up @@ -35,7 +35,7 @@ contract UniversalChanIbcContract is IbcMwUser, IbcUniversalPacketReceiver {
function sendGreet(address destPortAddr, bytes32 channelId, bytes calldata message, uint64 timeoutTimestamp) external {
IbcUniversalPacketSender(mw).sendUniversalPacket(
channelId,
Ibc.toBytes32(destPortAddr),
IbcUtils.toBytes32(destPortAddr),
message,
timeoutTimestamp
);
Expand All @@ -48,7 +48,7 @@ contract UniversalChanIbcContract is IbcMwUser, IbcUniversalPacketReceiver {
recvedPackets.push(UcPacketWithChannel(channelId, packet));
// do logic
// below is an example, the actual ackpacket data should be implemented by the contract developer
return AckPacket(true, abi.encodePacked(address(this), Ibc.toAddress(packet.srcPortAddr), 'ack-', packet.appData));
return AckPacket(true, abi.encodePacked(address(this), IbcUtils.toAddress(packet.srcPortAddr), 'ack-', packet.appData));
}

function onUniversalAcknowledgement(
Expand All @@ -60,7 +60,7 @@ contract UniversalChanIbcContract is IbcMwUser, IbcUniversalPacketReceiver {
// check onRecvUniversalPacket for the encoded ackpacket data
require(ack.data.length >= 20, 'ack data too short');
address ackSender = address(bytes20(ack.data[0:20]));
require(Ibc.toAddress(packet.destPortAddr) == ackSender, 'ack address mismatch');
require(IbcUtils.toAddress(packet.destPortAddr) == ackSender, 'ack address mismatch');
ackPackets.push(UcAckWithChannel(channelId, packet, ack));
// do logic
}
Expand Down
6 changes: 6 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[profile.default]
src = 'contracts'
out = 'out'
libs = ['node_modules', 'lib']
test = 'test'
cache_path = 'cache_forge'
10 changes: 9 additions & 1 deletion hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-foundry");

require('dotenv').config();

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
version: '0.8.20',
version: '0.8.23',
settings: {
optimizer: {
enabled: true,
Expand Down Expand Up @@ -34,5 +35,12 @@ module.exports = {
},
},
defaultNetwork: 'optimism',
paths: {
sources: './contracts',
tests: './test',
cache: './cache',
artifacts: './artifacts',
libraries: './lib',
}
};

1 change: 1 addition & 0 deletions lib/forge-std
Submodule forge-std added at ae570f
2 changes: 1 addition & 1 deletion lib/vibc-core-smart-contracts
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"homepage": "https://github.com/open-ibc/ibc-app-solidity-template#readme",
"devDependencies": {
"@nomicfoundation/hardhat-foundry": "^1.1.1",
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"hardhat": "^2.19.5"
},
Expand Down
3 changes: 1 addition & 2 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@open-ibc/vibc-core-smart-contracts/=lib/vibc-core-smart-contracts/
@openzeppelin/=lib/openzeppelin-contracts/
@lazyledger/protobuf3-solidity-lib/=lib/protobuf3-solidity-lib/
ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/

20 changes: 14 additions & 6 deletions scripts/create-channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,27 @@ async function main() {
const connHop2 = ibcConfig[chanConfig.dstChain].canonConnTo;
const srcPortId = addressToPortId(`polyibc.${chanConfig.srcChain}`, chanConfig.srcAddr);
const dstPortId = addressToPortId(`polyibc.${chanConfig.dstChain}`, chanConfig.dstAddr);

const local = {
portId: srcPortId,
channelId: hre.ethers.encodeBytes32String(''),
version: '',
};

const cp = {
portId: dstPortId,
channelId: hre.ethers.encodeBytes32String(''),
version: '',
};

// Create the channel
// Note: The proofHeight and proof are dummy values and will be dropped in the future
const tx = await ibcAppSrc.createChannel(
chanConfig.version,
local,
chanConfig.ordering,
chanConfig.fees,
[ connHop1, connHop2 ],
{
portId: dstPortId,
channelId: hre.ethers.encodeBytes32String(''),
version: '',
},
cp,
{
proofHeight: { revision_height: 0, revision_number: 0 },
proof: hre.ethers.encodeBytes32String('abc')
Expand Down
Loading