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

[DRAFT] Update contracts repo template #45

Closed
wants to merge 4 commits into from
Closed
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ Thumbs.db
.env.*
!.env.example
.vscode/

# IDE
.idea
3 changes: 0 additions & 3 deletions contracts/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@ HEDERA_PRIVATE_KEY_TYPE=ed25519
# testnet / mainnet
HEDERA_ENVIRONMENT=testnet

# dummy ipfs, needs to be replaced with a real one
NFT_METADATA_BASE_URL=ipfs://bafyreie3ichmqul4xa7e6xcy34tylbuq2vf3gnjf7c55trg3b6xyjr4bku/metadata.json


7 changes: 0 additions & 7 deletions contracts/.gitignore

This file was deleted.

21 changes: 21 additions & 0 deletions contracts/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) <YEAR> <COPYRIGHT HOLDER>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
20 changes: 20 additions & 0 deletions contracts/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# dependencies
update :; forge update

# install latest stable solc version
solc :; sudo add-apt-repository ppa:ethereum/ethereum && sudo apt-get update && sudo apt-get install solc

# build & test
build :; forge build
build-optimised :; forge build --optimize
test-forge :; forge test
test-gasreport :; forge test --gas-report
trace :; forge test -vvvvv
clean :; forge clean
snapshot :; forge snapshot

# chmod scripts
scripts :; chmod +x ./scripts/*

# fork mainnet with Hardhat
mainnet-fork :; npx hardhat node --fork ${ETH_MAINNET_RPC_URL}
276 changes: 186 additions & 90 deletions contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,186 @@
# Contract is work in progress

## What is covered?
- a simple and clean way to create a NFT via smart contract, in the Hedera way.
- as there is no way to send NFT to user wallets during mint (as it's possible in Eth), we are assigning the target wallet id upon mint. Later on, only the assigned wallet will be able to claim the NFT.

## What's needed?
- create BIDI fungible token and lock a certain amount on the NFT, upon minting. The contract will be re-deployed after that's done.

## Deploy the contract
To deploy the project as it is:
- to clear previous contract generations and artifacts ``pnpm run clear``
- to compile a fresh contract ``pnpm run compile``
- before deploying the contract, we have to make sure we added ``NFT_METADATA_URI`` in env variables as future NFT metadata will be saved under that folder. (https://pinata.cloud/ would be a nice place to start..)
- when everything is ready, run ``pnm run deploy`` and the contract will be deployed, and NFT collection created.

Logs after the deployment:
```html
> ts-node scripts/deploy.ts

Client setup complete.

----- Account Information -----
💰 Account Balance:
- 198.56787986 ℏ (HBAR)

----- Deployment Configuration -----
Operator Account: 0.0.4425801
Network: Testnet
Metadata URI: ipfs://bafyreie3ichmqul4xa7e6xcy34tylbuq2vf3gnjf7c55trg3b6xyjr4bku/metadata.json
HashScan Explorer: https://hashscan.io/testnet

----- Reading Contract -----
Contract bytecode size: 10689 bytes

----- Deploying Contract -----
Initiating contract deployment...
Contract deployed successfully!
Contract ID: 0.0.5266745
View Contract: https://hashscan.io/testnet/contract/0.0.5266745

----- Creating NFT Collection -----
Initiating NFT collection creation...
NFT Collection created successfully!
Collection Details:
- Token ID: 0.0.5266746
- Name: Fall Collection
- Symbol: LEAF
- Max Supply: 250
View Token: https://hashscan.io/testnet/token/0.0.5266746

----- Minting NFT -----
Initiating NFT minting...
NFT Minted successfully!
NFT Details:
- Serial Number: 1
- Token ID: 0.0.5266746
- Metadata: ipfs://bafyreie3ichmqul4xa7e6xcy34tylbuq2vf3gnjf7c55trg3b6xyjr4bku/metadata.json
- Allowed Claimer: 000000000000000000000000000000000001e240
View NFT: https://hashscan.io/testnet/token/0.0.5266746/1

----- Deployment Summary -----
Contract ID: 0.0.5266745
Token ID: 0.0.5266746
NFT Serial: 1

```

### Claim logs:

on successful claim:
```html
----- Claiming NFT -----
Initiating claim for NFT #1
NFT claimed successfully!
Claim Details:
- Token ID: 0.0.5266928
- Serial Number: 1
- New Owner: 0.0.4425801
View NFT: https://hashscan.io/testnet/token/0.0.5266928/1

```

if trying to claim a NFT assigned to another wallet
```html
----- Claiming NFT -----
Initiating claim for NFT #1
Error claiming NFT: receipt for transaction [email protected] contained error status CONTRACT_REVERT_EXECUTED

```
# Fully-Fledged Hardhat Project Template Based on TypeScript

[![🕵️‍♂️ Test smart contracts](https://github.com/blokk-studio/hardhat-project-template-ts/actions/workflows/test-contracts.yml/badge.svg)](https://github.com/blokk-studio/hardhat-project-template-ts/actions/workflows/test-contracts.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/license/mit)

## Installation

It is recommended to install [`pnpm`](https://pnpm.io) through the `npm` package manager, which comes bundled with [Node.js](https://nodejs.org/en) when you install it on your system. It is recommended to use a Node.js version `>= 22.0.0`.

Once you have `npm` installed, you can run the following both to install and upgrade `pnpm`:

```console
npm install -g pnpm
```

After having installed `pnpm`, simply run:

```console
pnpm install
```

## Running Deployments

> [!NOTE]
> The deployment script [`deploy.ts`](./scripts/deploy.ts) attempts to automatically verify the contract on the target chain after deployment. If you have not configured an API key, the verification will fail.

**Example Goerli:**

```console
pnpm deploy:goerli
```

> The deployment script [`deploy.ts`](./scripts/deploy.ts) includes the `tenderly` Hardhat Runtime Environment (HRE) extension with the `verify` method. Please consider uncommenting and configuring the Tenderly `project`, `username`, `forkNetwork`, `privateVerification`, and `deploymentsDir` attributes in the [`hardhat.config.ts`](./hardhat.config.ts) file before deploying or remove this call. Also, for this plugin to function you need to create a `config.yaml` file at `$HOME/.tenderly/config.yaml` or `%HOMEPATH%\.tenderly\config.yaml` and add an `access_key` field to it. For further information, see [here](https://github.com/Tenderly/hardhat-tenderly/tree/master/packages/hre-extender-v2#installing-tenderly-cli).

> For the deployment on the [ZKsync Era](https://docs.zksync.io/) test network, you must add your to-be-deployed contract artifact to [`deploy-zksync.ts`](./deploy/deploy-zksync.ts), enable `zksync` in the [`hardhat.config.ts`](./hardhat.config.ts#L121) file, and then run `pnpm compile` (in case you face any compilation issues, disable all configurations associated with the [`@tenderly/hardhat-tenderly`](https://github.com/Tenderly/hardhat-tenderly) plugin, including the `import` statement itself; see also [here](https://github.com/matter-labs/hardhat-zksync/issues/998) and [here](https://github.com/matter-labs/hardhat-zksync/issues/1174)). Next, fund your deployer account on ZKsync Era Testnet, setup the ZKsync-related configuration variables accordingly, and simply run `pnpm deploy:zksynctestnet`. Eventually, to verify the contract you can invoke: `npx hardhat verify --network zkSyncTestnet --constructor-args arguments.js <YOUR_CONTRACT_ADDRESS>`. The same approach applies if you want to deploy on the production network, except that you need to run `pnpm deploy:zksyncmain` and use `--network zkSyncMain` for the contract verification.

## Running `CREATE2` Deployments

```console
pnpm xdeploy
```

This template uses the [`xdeployer`](https://github.com/pcaversaccio/xdeployer) Hardhat plugin. Check out the documentation for more information on the specifics of the deployments.

## Configuration Variables

Run `npx hardhat vars set PRIVATE_KEY` to set the private key of your wallet. This allows secure access to your wallet to use with both testnet and mainnet funds during Hardhat deployments.

You can also run `npx hardhat vars setup` to see which other [configuration variables](https://hardhat.org/hardhat-runner/docs/guides/configuration-variables) are available.

## Using a Ledger Hardware Wallet

This template implements the [`hardhat-ledger`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ledger) plugin. Run `npx hardhat set LEDGER_ACCOUNT` and enter the address of the Ledger account you want to use.

## Using the Truffle Dashboard

> [!IMPORTANT]
> Truffle has been [sunsetted](https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat) by Consensys, but I still keep it in the template as I find it a very valuable tool. Please note that due to the lengthy loading time of Truffle Dashboard's `npm` package [`@truffle/dashboard-hardhat-plugin`](https://www.npmjs.com/package/@truffle/dashboard-hardhat-plugin), the module is disabled by default in the [`hardhat.config.ts`](./hardhat.config.ts) file. If you want to use it, you must uncomment the module import and the `truffle` configuration accordingly.

[Truffle](https://archive.trufflesuite.com) developed the [Truffle Dashboard](https://archive.trufflesuite.com/docs/truffle/how-to/use-the-truffle-dashboard/) to provide an easy way to use your existing MetaMask wallet for your deployments and for other transactions that you need to send from a command line context. Because the Truffle Dashboard connects directly to MetaMask it is also possible to use it in combination with hardware wallets like [Ledger](https://www.ledger.com) or [Trezor](https://trezor.io).

First, it is recommended that you install Truffle globally by running:

```console
npm install -g truffle
```

> If you have already installed Truffle, you need to ensure that you have at least version [`5.11.5`](https://github.com/trufflesuite/truffle/releases/tag/v5.11.5) installed and otherwise upgrade.

To start a Truffle Dashboard, you need to run the following command in a separate terminal window:

```console
truffle dashboard
```

By default, the command above starts a Truffle Dashboard at `http://localhost:24012` and opens the Dashboard in a new tab in your default browser. The Dashboard then prompts you to connect your wallet and confirm that you're connected to the right network. **You should double check your connected network at this point, since switching to a different network during a deployment can have unintended consequences.**

Eventually, in order to deploy with the Truffle Dashboard, you can simply run:

```console
pnpm deploy:dashboard
```

## Mainnet Forking

You can start an instance of the Hardhat network that forks the mainnet. This means that it will simulate having the same state as the mainnet, but it will work as a local development network. That way you can interact with deployed protocols and test complex interactions locally. To use this feature, you need to connect to an archive node.

This template is currently configured via the [`hardhat.config.ts`](./hardhat.config.ts) as follows:

```ts
forking: {
url: vars.get("ETH_MAINNET_URL", ethMainnetUrl),
// The Hardhat network will by default fork from the latest mainnet block
// To pin the block number, specify it below
// You will need access to a node with archival data for this to work!
// blockNumber: 14743877,
// If you want to do some forking, set `enabled` to true
enabled: false,
},
```

## Contract Verification

Change the contract address to your contract after the deployment has been successful. This works for both testnet and mainnet. You will need to get an API key from [etherscan](https://etherscan.io), [snowtrace](https://snowtrace.io) etc.

**Example:**

```console
npx hardhat verify --network fantomMain --constructor-args arguments.js <YOUR_CONTRACT_ADDRESS>
```

## Contract Interaction

This template includes an [example script](./scripts/interact.ts) that shows how to interact programmatically with a deployed contract. You must customise it according to your contract's specifications. The script can be simply invoked via:

```console
npx hardhat run scripts/interact.ts --network <network_name>
```

## Foundry

This template repository also includes the [Foundry](https://github.com/foundry-rs/foundry) toolkit as well as the [`@nomicfoundation/hardhat-foundry`](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-and-foundry) plugin.

> If you need help getting started with Foundry, I recommend reading the [📖 Foundry Book](https://book.getfoundry.sh).

### Dependencies

```console
make update
```

or

```console
forge update
```

### Compilation

```console
make build
```

or

```console
forge build
```

### Testing

To run only TypeScript tests:

```console
pnpm test:hh
```

To run only Solidity tests:

```console
pnpm test:forge
```

or

```console
make test-forge
```

To additionally display the gas report, you can run:

```console
make test-gasreport
```

### Deployment and Etherscan Verification

Inside the [`scripts/`](./scripts) folder are a few preconfigured scripts that can be used to deploy and verify contracts via Foundry. These scripts are required to be _executable_ meaning they must be made executable by running:

```console
make scripts
```

## Acknowledgement

This template is a public fork of [pcaversaccio](https://github.com/pcaversaccio)'s [template](https://github.com/pcaversaccio/hardhat-project-template-ts), licensed under the [MIT License](https://github.com/pcaversaccio/hardhat-project-template-ts/blob/main/LICENSE).
5 changes: 5 additions & 0 deletions contracts/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 🛡️ Security Policy

## 📬 Reporting a Vulnerability

Please report any security issues you find to [[email protected]](mailto:[email protected]).
21 changes: 21 additions & 0 deletions contracts/abis/contracts/src/NFTContract.sol/NFTContract.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[
"constructor()",
"event CallResponseEvent(bool,bytes)",
"event MinterAdded(address indexed)",
"event MinterRemoved(address indexed)",
"function addMinter(address)",
"function authorizedMinters(address) view returns (bool)",
"function claimNft(address,int64) returns (int256)",
"function claimed(int64) view returns (bool)",
"function createNft(string,string,string,int64,int64) payable returns (address)",
"function getClaimerAddress(int64) view returns (address)",
"function isMinter(address) view returns (bool)",
"function isNftClaimed(int64) view returns (bool)",
"function mintNftForUser(address,bytes[],address) returns (int64)",
"function nftClaimRights(int64) view returns (address)",
"function owner() view returns (address)",
"function redirectForToken(address,bytes) returns (int256, bytes)",
"function removeMinter(address)",
"function transferFrom(address,address,address,uint256) returns (int64)",
"function transferFromNFT(address,address,address,uint256) returns (int64)"
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
"event CallResponseEvent(bool,bytes)",
"function redirectForToken(address,bytes) returns (int256, bytes)",
"function transferFrom(address,address,address,uint256) returns (int64)",
"function transferFromNFT(address,address,address,uint256) returns (int64)"
]
Loading