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

refactor: counter example to use templating #61

Merged
merged 1 commit into from
Sep 13, 2023
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: 0 additions & 6 deletions messaging/counter/.eslintignore

This file was deleted.

47 changes: 0 additions & 47 deletions messaging/counter/.eslintrc.js

This file was deleted.

12 changes: 0 additions & 12 deletions messaging/counter/.gitignore

This file was deleted.

118 changes: 100 additions & 18 deletions messaging/counter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,75 @@ installed on your system.

## Getting Started

To get started, install the necessary dependencies by running the following
command in your terminal:
To get started, install the necessary dependencies:

```
yarn
```

## Hardhat Tasks

This template includes two Hardhat tasks that can be used to generate a random
wallet and request tokens from ZetaChain's faucet.
This template includes Hardhat tasks that can be used make it easier to build
with ZetaChain.

### Generating a Random Wallet

To generate a random wallet, run the following command in your terminal:
To generate a random wallet:

```
npx hardhat account --save
```

This will generate a random wallet, print information about the wallet to the
terminal, and save the private key to a `.env` file to make it accessible to
Hardhat. If you don't want to save the wallet (for example, if you just need an
address to send tokens to), you can run the command without the `--save` flag.
This command generates a random wallet, prints information about the wallet to
the terminal, and saves the private key to a `.env` file to make it accessible
to Hardhat. If you don't want to save the wallet (for example, if you just need
an address to send tokens to for testing purposes), you can run the command
without the `--save` flag.

### Querying for Token Balances

To query for token balances, run the following command in your terminal:
To query for token balances:

```
npx hardhat balances
```

This command will query token balances for the account address derived from the
This command queries token balances for the account address derived from the
private key specified in the `.env`.

If you want to query for token balances for a different account, you can use the
`--address` flag:

```
npx hardhat balances --address <address>
npx hardhat balances --address ADDRESS
```

### Requesting Tokens from the Faucet

To request tokens from ZetaChain's faucet using the account from the `.env`
file, run the following command in your terminal:
To request ZETA tokens from the faucet:

```
npx hardhat faucet
```

To install a standalone faucet, run the following command in your terminal:
This command requests tokens from the faucet for the account address derived
from the private key specified in the `.env`. Tokens sent to the address on
ZetaChain. To specify a different chain use a flag:

```
npm install -g @zetachain/faucet-cli
npx hardhat faucet --chain goerli_testnet
```

You can also specify a different address to send the tokens to:

```
npx hardhat faucet --address ADDRESS
```

Alternatively, you can install a standalone faucet CLI:

```
yarn global add @zetachain/faucet-cli@athens3
```

You can then use it with the following command:
Expand All @@ -75,12 +88,49 @@ You can then use it with the following command:
zetafaucet -h
```

### Creating an Omnichain Contract

To create a new omnichain contract:

```
npx hardhat omnichain MyContract
```

This command creates a new omnichain contract in `contracts/MyContract.sol`, a
task to deploy the contract in `tasks/deploy.ts`, and a task to interact with
the contract in `tasks/interact.ts`.

When an omnichain contract is called, it can receive data in the `data` field of
a transaction. This data is passed to the `message` parameter of the contract's
`onCrossChainCall` function. To specify the fields of the `message` parameter,
use positional arguments:

```
npx hardhat omnichain MyContract recepient:address description quantity:uint256
```

A field may have a type specified after the field name, separated by a colon. If
no type is specified, the type defaults to `bytes32`.

Learn more about omnichain contracts by following the
[tutorials](https://www.zetachain.com/docs/developers/omnichain/tutorials/hello/).

### Tracking a Cross-Chain Transaction

After broadcasting a cross-chain transaction on a connected chain either to a
cross-chain messaging contract or to trigger an omnichain contract, you can
track its status:

```
npx hardhat cctx --tx TX_HASH
```

### Verifying a Contract

You can verify a deployed contract with the following command:
To verify a contract deployed on ZetaChain:

```
npx hardhat verify:zeta --contract <address>
npx hardhat verify:zeta --contract ADDRESS
```

Select the contract to verify:
Expand All @@ -94,6 +144,38 @@ Select the contract to verify:

After the confirmation the contract will be verified.

### Sending Tokens

Sending ZETA from ZetaChain to Goerli:

```
npx hardhat send-zeta --amount 1 --network zeta_testnet --destination goerli_testnet
```

Sending ZETA from Goerli to ZetaChain:

```
npx hardhat send-zeta --amount 1 --network goerli_testnet --destination zeta_testnet
```

Depositing gETH to ZetaChain as ZRC-20:

```
npx hardhat send-zrc20 --amount 1 --network goerli_testnet --destination zeta_testnet
```

Withdrawing ZRC-20 from ZetaChain go Goerli as gETH:

```
npx hardhat send-zrc20 --amount 1 --network zeta_testnet --destination goerli_testnet
```

Depositing tBTC from the Bitcoin testnet to ZetaChain:

```
npx hardhat send-btc --amount 1 --recipient TSS_ADDRESS --memo RECIPIENT_ADDRESS_WITHOUT_0x
```

## Next Steps

To learn more about building decentralized apps on ZetaChain, follow the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "@zetachain/protocol-contracts/contracts/evm/tools/ZetaInteractor.sol";
import "@zetachain/protocol-contracts/contracts/evm/interfaces/ZetaInterfaces.sol";

interface CrossChainCounterErrors {
interface CounterErrors {
error InvalidMessageType();

// highlight-next-line
error DecrementOverflow();
}

contract CrossChainCounter is
ZetaInteractor,
ZetaReceiver,
CrossChainCounterErrors
{
bytes32 public constant CROSS_CHAIN_INCREMENT_MESSAGE =
keccak256("CROSS_CHAIN_INCREMENT");
contract Counter is ZetaInteractor, ZetaReceiver, CounterErrors {
bytes32 public constant COUNTER_MESSAGE_TYPE =
keccak256("CROSS_CHAIN_COUNTER");

event CounterEvent(address);
event CounterRevertedEvent(address);
mapping(address => uint256) public counter;

ZetaTokenConsumer private immutable _zetaConsumer;
Expand All @@ -34,7 +32,8 @@ contract CrossChainCounter is
_zetaConsumer = ZetaTokenConsumer(zetaConsumerAddress);
}

function crossChainCount(uint256 destinationChainId) external payable {
// highlight-next-line
function sendMessage(uint256 destinationChainId) external payable {
if (!_isValidChainId(destinationChainId))
revert InvalidDestinationChainId();

Expand All @@ -50,7 +49,8 @@ contract CrossChainCounter is
destinationChainId: destinationChainId,
destinationAddress: interactorsByChainId[destinationChainId],
destinationGasLimit: 300000,
message: abi.encode(CROSS_CHAIN_INCREMENT_MESSAGE, msg.sender),
// highlight-next-line
message: abi.encode(COUNTER_MESSAGE_TYPE, msg.sender),
zetaValueAndGas: zetaValueAndGas,
zetaParams: abi.encode("")
})
Expand All @@ -60,29 +60,32 @@ contract CrossChainCounter is
function onZetaMessage(
ZetaInterfaces.ZetaMessage calldata zetaMessage
) external override isValidMessageCall(zetaMessage) {
(bytes32 messageType, address messageFrom) = abi.decode(
(bytes32 messageType, address from) = abi.decode(
zetaMessage.message,
(bytes32, address)
);

if (messageType != CROSS_CHAIN_INCREMENT_MESSAGE)
revert InvalidMessageType();
if (messageType != COUNTER_MESSAGE_TYPE) revert InvalidMessageType();

counter[messageFrom]++;
// highlight-next-line
counter[from]++;
emit CounterEvent(from);
}

function onZetaRevert(
ZetaInterfaces.ZetaRevert calldata zetaRevert
) external override isValidRevertCall(zetaRevert) {
(bytes32 messageType, address messageFrom) = abi.decode(
(bytes32 messageType, address from) = abi.decode(
zetaRevert.message,
(bytes32, address)
);

if (messageType != CROSS_CHAIN_INCREMENT_MESSAGE)
revert InvalidMessageType();
if (counter[messageFrom] <= 0) revert DecrementOverflow();
if (messageType != COUNTER_MESSAGE_TYPE) revert InvalidMessageType();

counter[messageFrom]--;
// highlight-start
if (counter[from] <= 0) revert DecrementOverflow();
counter[from]--;
// highlight-end
emit CounterRevertedEvent(from);
}
}
6 changes: 3 additions & 3 deletions messaging/counter/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import "@nomicfoundation/hardhat-toolbox";
import "./tasks/interact";
import "./tasks/deploy";
import "./tasks/counter_increment";
import "./tasks/counter_show";
import "@nomicfoundation/hardhat-toolbox";
import "@zetachain/toolkit/tasks";

import { getHardhatConfigNetworks } from "@zetachain/networks";
import { HardhatUserConfig } from "hardhat/config";
import "@zetachain/toolkit/tasks";

const config: HardhatUserConfig = {
networks: {
Expand Down
2 changes: 0 additions & 2 deletions messaging/counter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
"devDependencies": {
"@ethersproject/abi": "^5.4.7",
"@ethersproject/providers": "^5.4.7",
"@inquirer/select": "^1.1.3",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.0",
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-etherscan": "^3.0.0",
"@openzeppelin/contracts": "^4.9.0",
"@typechain/ethers-v5": "^10.1.0",
"@typechain/hardhat": "^6.1.2",
"@types/chai": "^4.2.0",
Expand Down
2 changes: 1 addition & 1 deletion messaging/counter/tasks/counter_show.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";

const contractName = "CrossChainCounter";
const contractName = "Counter";

const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
const [signer] = await hre.ethers.getSigners();
Expand Down
2 changes: 1 addition & 1 deletion messaging/counter/tasks/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { getSupportedNetworks } from "@zetachain/networks";

const contractName = "CrossChainCounter";
const contractName = "Counter";

const main = async (args: any, hre: HardhatRuntimeEnvironment) => {
const networks = args.networks.split(",");
Expand Down
Loading
Loading