From f7d796bf66c5cef6f09bd2c323217d86a6551121 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Tue, 20 Aug 2024 16:27:35 +0300 Subject: [PATCH] wip --- universal/hello/contracts/Hello.sol | 34 ++++++++--- universal/hello/contracts/RevertContract.sol | 4 +- universal/hello/hardhat.config.ts | 1 + universal/hello/package.json | 5 +- universal/hello/tasks/callFromZetaChain.ts | 63 ++++++++++++++++++++ universal/hello/tasks/interact.ts | 14 +++-- 6 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 universal/hello/tasks/callFromZetaChain.ts diff --git a/universal/hello/contracts/Hello.sol b/universal/hello/contracts/Hello.sol index eb4cfec2..5d93241b 100644 --- a/universal/hello/contracts/Hello.sol +++ b/universal/hello/contracts/Hello.sol @@ -3,26 +3,44 @@ pragma solidity 0.8.26; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {RevertContext} from "@zetachain/protocol-contracts/contracts/Revert.sol"; +import {RevertContext, RevertOptions} from "@zetachain/protocol-contracts/contracts/Revert.sol"; import "@zetachain/protocol-contracts/contracts/zevm/interfaces/UniversalContract.sol"; +import "@zetachain/protocol-contracts/contracts/zevm/interfaces/IGatewayZEVM.sol"; contract Hello is UniversalContract { - event HelloEvent(string message); + event HelloEvent(string, string); event ContextDataRevert(RevertContext revertContext); + address constant gateway = 0x610178dA211FEF7D417bC0e6FeD39F05609AD788; + function onCrossChainCall( zContext calldata context, address zrc20, uint256 amount, bytes calldata message ) external override { - emit HelloEvent("Hello from a universal app"); - revert("REVERTING!!!"); - // string memory decodedMessage; - // if (message.length > 0) { - // decodedMessage = abi.decode(message, (string)); - // } + string memory decodedMessage; + if (message.length > 0) { + decodedMessage = abi.decode(message, (string)); + } + emit HelloEvent("Hello from a universal app", decodedMessage); + } + + function callFromZetaChain( + bytes memory receiver, + address zrc20, + bytes calldata message, + uint256 gasLimit, + RevertOptions memory revertOptions + ) external { + IGatewayZEVM(gateway).call( + receiver, + zrc20, + message, + gasLimit, + revertOptions + ); } function onRevert(RevertContext calldata revertContext) external override { diff --git a/universal/hello/contracts/RevertContract.sol b/universal/hello/contracts/RevertContract.sol index eb046e66..7c712aed 100644 --- a/universal/hello/contracts/RevertContract.sol +++ b/universal/hello/contracts/RevertContract.sol @@ -12,8 +12,8 @@ contract RevertContract { event ContextDataRevert(RevertContext revertContext); function onRevert(RevertContext calldata revertContext) external { - emit ContextDataRevert(revertContext); - // emit RevertEvent("Event from RevertContract!!!"); + // emit ContextDataRevert(revertContext); + emit RevertEvent("Event from RevertContract!!!"); } receive() external payable {} diff --git a/universal/hello/hardhat.config.ts b/universal/hello/hardhat.config.ts index 66c70ea4..09bcc24f 100644 --- a/universal/hello/hardhat.config.ts +++ b/universal/hello/hardhat.config.ts @@ -1,5 +1,6 @@ import "./tasks/interact"; import "./tasks/deploy"; +import "./tasks/callFromZetaChain"; import "./tasks/solana/interact"; import "@zetachain/localnet/tasks"; import "@nomicfoundation/hardhat-toolbox"; diff --git a/universal/hello/package.json b/universal/hello/package.json index ca1fd2a6..4c74a78c 100644 --- a/universal/hello/package.json +++ b/universal/hello/package.json @@ -6,7 +6,8 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "lint:fix": "npx eslint . --ext .js,.ts --fix", - "lint": "npx eslint . --ext .js,.ts" + "lint": "npx eslint . --ext .js,.ts", + "deploy": "npx hardhat compile --force && npx hardhat deploy --network localhost --name Hello && npx hardhat deploy --network localhost --name RevertContract" }, "keywords": [], "author": "", @@ -58,4 +59,4 @@ "@solana/spl-memo": "^0.2.5", "@solana/web3.js": "^1.95.2" } -} +} \ No newline at end of file diff --git a/universal/hello/tasks/callFromZetaChain.ts b/universal/hello/tasks/callFromZetaChain.ts new file mode 100644 index 00000000..2578f87f --- /dev/null +++ b/universal/hello/tasks/callFromZetaChain.ts @@ -0,0 +1,63 @@ +import { task, types } from "hardhat/config"; +import type { HardhatRuntimeEnvironment } from "hardhat/types"; +import { utils } from "ethers"; + +const main = async (args: any, hre: HardhatRuntimeEnvironment) => { + const [signer] = await hre.ethers.getSigners(); + + const contractArtifact = await hre.artifacts.readArtifact("Hello"); + const contract = new hre.ethers.Contract( + args.contract, + contractArtifact.abi, + signer + ); + + const message = hre.ethers.utils.defaultAbiCoder.encode( + ["string"], + [args.message] + ); + + const revertMessageBytes = hre.ethers.utils.toUtf8Bytes(args.revertMessage); + + try { + const tx = await contract.callFromZetaChain( + hre.ethers.utils.hexlify(args.receiver), + args.zrc20, + message, + args.gasLimit, + { + revertAddress: args.revertAddress, + callOnRevert: args.callOnRevert, + abortAddress: "0x0000000000000000000000000000000000000000", // not used + revertMessage: hre.ethers.utils.hexlify(revertMessageBytes), + }, + { + gasPrice: 10000000000, + gasLimit: 7000000, + } + ); + + await tx.wait(); + console.log("Successfully called the contract on ZetaChain!"); + } catch (e) { + console.error("Error calling contract:", e); + } +}; + +task( + "call-from-zetachain", + "Calls the callFromZetaChain function on a universal app", + main +) + .addParam("message", "A message") + .addParam("contract", "The address of the universal app on ZetaChain") + .addOptionalParam( + "zrc20", + "The address of the ZRC20 token", + "0x9fd96203f7b22bCF72d9DCb40ff98302376cE09c" + ) + .addParam("gasLimit", "The gas limit for the transaction", 7000000, types.int) + .addFlag("callOnRevert", "Whether to call on revert") + .addParam("revertAddress") + .addParam("revertMessage") + .addParam("receiver", "The address of the receiver contract on EVM"); diff --git a/universal/hello/tasks/interact.ts b/universal/hello/tasks/interact.ts index c29b7b37..7ce14da4 100644 --- a/universal/hello/tasks/interact.ts +++ b/universal/hello/tasks/interact.ts @@ -1,4 +1,4 @@ -import { task } from "hardhat/config"; +import { task, types } from "hardhat/config"; import type { HardhatRuntimeEnvironment } from "hardhat/types"; import GatewayABI from "@zetachain/protocol-contracts/abi/GatewayEVM.sol/GatewayEVM.json"; import { utils } from "ethers"; @@ -12,14 +12,16 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => { signer ); + const revertMessageBytes = hre.ethers.utils.toUtf8Bytes(args.revertMessage); + const message = hre.ethers.utils.defaultAbiCoder.encode( ["string"], [args.name] ); try { const callTx = await gateway[ - "depositAndCall(address,bytes,(address,bool,address,bytes))" - // "call(address,bytes,(address,bool,address,bytes))" + // "depositAndCall(address,bytes,(address,bool,address,bytes))" + "call(address,bytes,(address,bool,address,bytes))" ]( args.contract, message, @@ -27,12 +29,12 @@ const main = async (args: any, hre: HardhatRuntimeEnvironment) => { revertAddress: args.revertAddress, callOnRevert: args.callOnRevert, abortAddress: "0x0000000000000000000000000000000000000000", // not used - revertMessage: args.revertMessage, + revertMessage: hre.ethers.utils.hexlify(revertMessageBytes), }, { gasPrice: 10000000000, gasLimit: 7000000, - value: hre.ethers.utils.parseEther(args.amount), + // value: hre.ethers.utils.parseEther(args.amount), } ); await callTx.wait(); @@ -52,7 +54,7 @@ task("interact", "calls zevm zcontract from evm account", main) "contract address of gateway on EVM", "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0" ) + .addFlag("callOnRevert", "Whether to call on revert") .addParam("revertAddress") - .addFlag("callOnRevert") .addParam("revertMessage") .addParam("amount", "amount of ETH to send with the transaction");