From 4f1ee86c2a6591e737d841a6e1a5430fafde0287 Mon Sep 17 00:00:00 2001 From: Interconnection - Andreas Kuballa Date: Sun, 20 Oct 2024 02:00:35 -0300 Subject: [PATCH 1/2] Added Documentation, MaGGA Sender and Receiver Contract --- README.md | 90 +++++++++++++++++++++++++++++++ contracts/MaGGA/receiverMaGGA.sol | 23 ++++++++ contracts/MaGGA/senderMaGGA.sol | 29 ++++++++++ foundry.toml | 1 + 4 files changed, 143 insertions(+) create mode 100644 contracts/MaGGA/receiverMaGGA.sol create mode 100644 contracts/MaGGA/senderMaGGA.sol diff --git a/README.md b/README.md index c8cf76fc..725fd445 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,93 @@ +# Interchain Connection between Fuji C-Chain and MaGGA L1 Chain + +Important variables: + +``` + +MaGGA_BLOCKCHAIN_ID = 0x02f8b60b4d4070cf62e67802fe6532d4fcfc6582b4048d040ed6cfc7247d86d8 +MaGGA_RPC = "https://subnets.avax.network/gaming/testnet/rpc" + +FUJI_C_BLOCKCHAIN_ID = 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC +FUJI_RPC = "https://api.avax-test.network/ext/bc/C/rpc" + +``` + + +1. Set up privat the privat key of your crypto wallet: + +``` +export PK=YOUR_PRIVATE_KEY +``` + + +2. Deploy Sender Contract on C chain + +``` +forge create --rpc-url fuji-c --private-key $PK contracts/MaGGA/senderMaGGA.sol:SenderOnCChain +``` + + +The output should look like this: + +``` +[⠊] Compiling... +[⠢] Compiling 2 files with Solc 0.8.18 +[⠆] Solc 0.8.18 finished in 158.51ms +Compiler run successful! +Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC +Deployed to: 0xAAASENDER_CONTRACT_ADDRESS888 +Transaction hash: 0x48a1ffaa8aa8011f842147a908ff35a1ebfb75a5a07eb37ae96a4cc8d7feafd7 +``` + +3. If you are using Avacloud, authorize the Sender Contract on your L1 Blockchain. + +4. Save the adress where the smart constract was deployed to: + +``` +export SENDER_CONTRACT_ADDRESS=0xAAASENDER_CONTRACT_ADDRESS888 +``` + + +5. Deploy Receiver Contract on MaGGA chain: + +``` +forge create --rpc-url MaGGA --private-key $PK contracts/MaGGA/receiverMaGGA.sol:ReceiverOnSubnet +``` + +The output should look like this: + +``` +[⠊] Compiling... +[⠒] Compiling 2 files with Solc 0.8.18 +[⠢] Solc 0.8.18 finished in 81.53ms +Compiler run successful! +Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC +Deployed to: 0xYYYRECEIVER_CONTRACT_ADDRESS444 +Transaction hash: 0xcde7873e9e3c68fb00a2ad6644dceb64a01a41941da46de5a0f559d6d70a1638 +``` + +6. If you are using Avacloud, authorize the Sender Contract on your L1 Blockchain. + +7. Save the adress where the smart constract was deployed to, executing the : + +``` +export RECEIVER_CONTRACT_ADDRESS=0xYYYRECEIVER_CONTRACT_ADDRESS444 +``` + +8. Send Transaction from C-Chain to MaGGA L1 Chain: + +``` +cast send --rpc-url MaGGA --private-key $PK $SENDER_CONTRACT_ADDRESS "sendMessage(address,string)" $RECEIVER_CONTRACT_ADDRESS "Hello MaGGA!" +``` + +9. Read variable on MaGGA L1 Chain to make sure, that the right message was received: + +``` +cast call --rpc-url MaGGA $RECEIVER_CONTRACT_ADDRESS "lastMessage()(string)" +``` + + + # Avalanche Starter Kit This starter kit will get you started with developing solidity smart contract dApps on the C-Chain or on an Avalanche L1. It provides all tools to build cross-L1 dApps using Teleporter. It includes: diff --git a/contracts/MaGGA/receiverMaGGA.sol b/contracts/MaGGA/receiverMaGGA.sol new file mode 100644 index 00000000..be35645c --- /dev/null +++ b/contracts/MaGGA/receiverMaGGA.sol @@ -0,0 +1,23 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity ^0.8.18; + +import "@teleporter/ITeleporterMessenger.sol"; +import "@teleporter/ITeleporterReceiver.sol"; + +contract ReceiverOnSubnet is ITeleporterReceiver { + ITeleporterMessenger public immutable messenger = ITeleporterMessenger(0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf); + + string public lastMessage; + + function receiveTeleporterMessage(bytes32, address, bytes calldata message) external { + // Only the Teleporter receiver can deliver a message. + require(msg.sender == address(messenger), "ReceiverOnSubnet: unauthorized TeleporterMessenger"); + + // Store the message. + lastMessage = abi.decode(message, (string)); + } +} diff --git a/contracts/MaGGA/senderMaGGA.sol b/contracts/MaGGA/senderMaGGA.sol new file mode 100644 index 00000000..11a6f8a4 --- /dev/null +++ b/contracts/MaGGA/senderMaGGA.sol @@ -0,0 +1,29 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity ^0.8.18; + +import "@teleporter/ITeleporterMessenger.sol"; + +contract SenderOnCChain { + ITeleporterMessenger public immutable messenger = ITeleporterMessenger(0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf); + + /** + * @dev Sends a message to another chain. + */ + function sendMessage(address destinationAddress, string calldata message) external { + messenger.sendCrossChainMessage( + TeleporterMessageInput({ + // Replace with blockchainID of your Subnet (see instructions in Readme) + destinationBlockchainID: 0x02f8b60b4d4070cf62e67802fe6532d4fcfc6582b4048d040ed6cfc7247d86d8, + destinationAddress: destinationAddress, + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(0), amount: 0}), + requiredGasLimit: 100000, + allowedRelayerAddresses: new address[](0), + message: abi.encode(message) + }) + ); + } +} diff --git a/foundry.toml b/foundry.toml index 4261b7d6..3942abc4 100644 --- a/foundry.toml +++ b/foundry.toml @@ -11,6 +11,7 @@ myblockchain = "http://localhost:9650/ext/bc/myblockchain/rpc" fuji-c = "https://api.avax-test.network/ext/bc/C/rpc" dispatch = "https://subnets.avax.network/dispatch/testnet/rpc" mysubnet = "http://localhost:9650/ext/bc/mysubnet/rpc" +MaGGA = "https://subnets.avax.network/gaming/testnet/rpc" # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options From 343c2a20f61f6b0a07a28b3360f0ae0a48cecf80 Mon Sep 17 00:00:00 2001 From: Interconnection - Andreas Kuballa Date: Sun, 20 Oct 2024 06:52:59 -0300 Subject: [PATCH 2/2] Added smart contracts for creating a Token, sending an amount and creating/receiving tokens --- README.md | 105 ++++++++++++++++++++++++- contracts/MaGGA/createToken.sol | 19 +++++ contracts/MaGGA/receiveMaGGATokens.sol | 30 +++++++ contracts/MaGGA/sendAmount.sol | 29 +++++++ 4 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 contracts/MaGGA/createToken.sol create mode 100644 contracts/MaGGA/receiveMaGGATokens.sol create mode 100644 contracts/MaGGA/sendAmount.sol diff --git a/README.md b/README.md index 725fd445..92634dbd 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,9 @@ FUJI_RPC = "https://api.avax-test.network/ext/bc/C/rpc" ``` +# Create simple interchain messaging between Fuji C-Chain and MaGGA L1 Chain -1. Set up privat the privat key of your crypto wallet: +1. Set up privat the privat key of your crypto wallet and save it as an environmental variable: ``` export PK=YOUR_PRIVATE_KEY @@ -87,6 +88,108 @@ cast call --rpc-url MaGGA $RECEIVER_CONTRACT_ADDRESS "lastMessage()(string)" ``` +# Create simple token creation in MaGGA L1 Chain depending on a message from the Fuji C-Chain + +1. If you do not have already set up a privat key, please refer to Step 1 of "Create simple interchain messaging between Fuji C-Chain and MaGGA L1 Chain": + +``` +export PK=YOUR_PRIVATE_KEY +``` + + +2. Deploy the token creation contract on Fuji C-chain: + +``` +forge create --rpc-url fuji-c --private-key $PK contracts/MaGGA/createToken.sol:MyToken +``` + + +The output should look like this: + +``` +[⠊] Compiling... +[⠢] Compiling 2 files with Solc 0.8.18 +[⠆] Solc 0.8.18 finished in 158.51ms +Compiler run successful! +Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC +Deployed to: 0xAAATOKEN_CREATION_CONTRACT_ADDRESS888 +Transaction hash: 0x48a1ffaa8aa8011f842147a908ff35a1ebfb75a5a07eb37ae96a4cc8d7feafd7 +``` + +3. If you are using Avacloud, authorize the token creation smart contract (i.e. 0xAAATOKEN_CREATION_CONTRACT_ADDRESS888) on your L1 Blockchain. + +4. Save the adress where the token creation smart contract was deployed to as an environmental variable: + +``` +export TOKEN_CREATION_CONTRACT_ADDRESS=0xAAATOKEN_CREATION_CONTRACT_ADDRESS888 +``` + +5. Deploy Sender Contract on C chain + +``` +forge create --rpc-url fuji-c --private-key $PK contracts/MaGGA/sendAmount.sol:SendAmountOnCChain +``` + + +The output should look like this: + +``` +[⠊] Compiling... +[⠢] Compiling 2 files with Solc 0.8.18 +[⠆] Solc 0.8.18 finished in 158.51ms +Compiler run successful! +Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC +Deployed to: 0xAAASENDER_CONTRACT_ADDRESS888 +Transaction hash: 0x48a1ffaa8aa8011f842147a908ff35a1ebfb75a5a07eb37ae96a4cc8d7feafd7 +``` + +6. If you are using Avacloud, authorize the sender smart contract (i.e. 0xAAASENDER_CONTRACT_ADDRESS888) on your L1 Blockchain. + +7. Save the adress where the sender smart contract was deployed to as an environmental variable: + +``` +export SENDER_CONTRACT_ADDRESS=0xAAASENDER_CONTRACT_ADDRESS888 +``` + +8. Deploy Receiver Contract on MaGGA chain: + +``` +forge create --rpc-url MaGGA --private-key $PK contracts/MaGGA/receiveMaGGATokens.sol:ReceiveMaGGATokens +``` + +The output should look like this: + +``` +[⠊] Compiling... +[⠒] Compiling 2 files with Solc 0.8.18 +[⠢] Solc 0.8.18 finished in 81.53ms +Compiler run successful! +Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC +Deployed to: 0xYYYRECEIVER_CONTRACT_ADDRESS444 +Transaction hash: 0xcde7873e9e3c68fb00a2ad6644dceb64a01a41941da46de5a0f559d6d70a1638 +``` + +9. If you are using Avacloud, authorize the Receiver Contract (i.e. 0xYYYRECEIVER_CONTRACT_ADDRESS444) on your L1 Blockchain. + +10. Save the adress where the receiver smart constract was deployed to as an environmental varaible: + +``` +export RECEIVER_CONTRACT_ADDRESS=0xYYYRECEIVER_CONTRACT_ADDRESS444 +``` + +11. Send Transaction from C-Chain to MaGGA L1 Chain: + +``` +cast send --rpc-url MaGGA --private-key $PK $SENDER_CONTRACT_ADDRESS "sendAmount(address,uint)" $RECEIVER_CONTRACT_ADDRESS 100 +``` + +12. Read variable on MaGGA L1 Chain to make sure, that the right message was received: + +``` +cast call --rpc-url MaGGA $RECEIVER_CONTRACT_ADDRESS "lastAmount()(uint)" +``` + + # Avalanche Starter Kit diff --git a/contracts/MaGGA/createToken.sol b/contracts/MaGGA/createToken.sol new file mode 100644 index 00000000..e325540c --- /dev/null +++ b/contracts/MaGGA/createToken.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +// Compatible with OpenZeppelin Contracts ^5.0.0 +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts@5.0.2/access/Ownable.sol"; +import "@openzeppelin/contracts@5.0.2/token/ERC20/extensions/ERC20Permit.sol"; + +contract MyToken is ERC20, Ownable, ERC20Permit { + constructor(address initialOwner) + ERC20("MyToken", "MTK") + Ownable(initialOwner) + ERC20Permit("MyToken") + {} + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } +} \ No newline at end of file diff --git a/contracts/MaGGA/receiveMaGGATokens.sol b/contracts/MaGGA/receiveMaGGATokens.sol new file mode 100644 index 00000000..9a223116 --- /dev/null +++ b/contracts/MaGGA/receiveMaGGATokens.sol @@ -0,0 +1,30 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity ^0.8.18; + +import "@teleporter/ITeleporterMessenger.sol"; +import "@teleporter/ITeleporterReceiver.sol"; +import "./createToken.sol"; + +contract ReceiveMaGGATokens is ITeleporterReceiver { + ITeleporterMessenger public immutable messenger = ITeleporterMessenger(0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf); + MyToken public tokenNetwork; + uint public lastAmount; + address public receiver; + constructor(address token, address _receiver) { + tokenNetwork = new MyToken(token); + receiver = _receiver; + } + function receiveTeleporterMessage(bytes32, address, uint calldata amount) external { + // Only the Teleporter receiver can deliver a message. + require(msg.sender == address(messenger), "ReceiverOnSubnet: unauthorized TeleporterMessenger"); + + // Store the message. + lastAmount = abi.decode(amount, (uint)); + tokenNetwork.mint(receiver, lastAmount); + + } +} diff --git a/contracts/MaGGA/sendAmount.sol b/contracts/MaGGA/sendAmount.sol new file mode 100644 index 00000000..89225d5d --- /dev/null +++ b/contracts/MaGGA/sendAmount.sol @@ -0,0 +1,29 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity ^0.8.18; + +import "@teleporter/ITeleporterMessenger.sol"; + +contract SendAmountOnCChain { + ITeleporterMessenger public immutable messenger = ITeleporterMessenger(0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf); + + /** + * @dev Sends a amount to another chain. + */ + function sendAmount(address destinationAddress, uint calldata amount) external { + messenger.sendCrossChainMessage( + TeleporterMessageInput({ + // Replace with blockchainID of your Subnet (see instructions in Readme) + destinationBlockchainID: 0x02f8b60b4d4070cf62e67802fe6532d4fcfc6582b4048d040ed6cfc7247d86d8, + destinationAddress: destinationAddress, + feeInfo: TeleporterFeeInfo({feeTokenAddress: address(0), amount: 0}), + requiredGasLimit: 100000, + allowedRelayerAddresses: new address[](0), + amount: abi.encode(amount) + }) + ); + } +}