Skip to content

Commit

Permalink
Merge pull request #2 from LionelB5/add-tests
Browse files Browse the repository at this point in the history
Test contract & mock LINK dependencies
  • Loading branch information
LionelB5 committed Jan 21, 2022
2 parents 2e2d12f + 099e7cf commit b60b1c4
Show file tree
Hide file tree
Showing 15 changed files with 33,637 additions and 18,376 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -6,5 +6,6 @@ typechain
typechain-types

#Hardhat files
cache
artifacts
cache
deployments
32 changes: 17 additions & 15 deletions README.md
Expand Up @@ -68,7 +68,7 @@ When deploying our smart contract, we may deploy to our local blockchain, or to
To deploy the contract locally, simply execute:

```bash
npx hardhat run scripts/deploy.ts
npx hardhat deploy
```

This will compile and deploy the smart contract to your local `hardhat` network.
Expand All @@ -81,18 +81,20 @@ network is very quick, and good for running tests and checking if our contracts
successfully, but if one wants to actually interact with the deployed contract, its better
to deploy to the `localhost` network (not to be confused with the `hardhat` network!).

Before we can deploy to our `localhost` network, we need to spin up our own local node.
This can be easily done by executing:
Executing the command to spin up a local node will automatically run the deployment scripts
in the `deployments` folder, so we won't have to execute a `npx hardhat deploy`.

This spin up a local node, execute:

```bash
npx hardhat node
# optionally supply the `no-deploy` flag to prevent any deployments from executing
npx hardhat node --network localhost
```

This will spin up a local node that we can use for our deployment. To deploy to this local node,
in another terminal, execute:
To manually deploy to this local node, in another terminal, execute:

```bash
npx hardhat run scripts/deploy.ts --network localhost
npx hardhat deploy --network localhost
```

At this point, if you check in on your node, you'll see some logs indicating that the contract was
Expand All @@ -111,6 +113,8 @@ const contract = await ethers.getContractAt("CryptoBooks", contractAddress);
balance = await contract.balanceOf('<address_here>');
```

TODO: Document mocking of Chainlink VRF Coordinator and Link Token in local environments

### Deployment to a remote blockchain (testnet)

Before deploying to the testnet, ensure you have some testnet MATIC; since we are modifying
Expand All @@ -122,15 +126,9 @@ key stored in your `.env` file.
To deploy to the testnet execute:

```
npx hardhat run scripts/deploy.ts --network polygon_testnet
npx hardhat deploy --network polygon_testnet
```

**Note:** There is currently a bug with hardhat and the polygon testnet, it's likely the address printed to your terminal
purported to be the deployed contract's address on the blockchain is inaccurate. See
[this github issue](https://github.com/nomiclabs/hardhat/issues/2162) for more details. To retrieve the correct address of your
deployed contract, navigate to polygonscan and look up your wallet address (corresponding to the private key in your `.env` file).
From here you should see a record of the contract creation, along with the contracts actual address.

You're now free to interact with the contract as described in `Deployment to a local blockchain` by spinning up a hardhat console:

```
Expand All @@ -146,7 +144,7 @@ via MetaMask.
**Note:** Do note what is mentioned in the previous section, there is a bug with HardHat and the polygon testnet, so ensure you
retrieve the correct contract address for verification.

This can be done by executing the following command:
To verify the contract, execute the following command:

```
npx hardhat verify --network polygon_testnet <contract address> <... parameters provided to contract constructor at deploy time>
Expand All @@ -157,3 +155,7 @@ For example, to verify the contract in this repository you would execute:
```
npx hardhat verify --network polygon_testnet <contract address> 0x8C7382F9D8f56b33781fE506E897a4F1e2d17255 0x326C977E6efc84E512bB9C30f76E30c160eD06FB 0x6e75b569a01ef56d18cab6a8e71e6600d6ce853834d4a5748b720d06f878b3a4
```

TODO: This verification process should be easily automatable (prevent having to provide parameters manually)

TODO: Document test execution and mock configuration
2 changes: 1 addition & 1 deletion TUTORIAL.md
Expand Up @@ -23,7 +23,7 @@ Ensure you have followed the following sections described in the `README.md`:
First, we'll deploy our contract to the Polygon testnet. To do so, execute:

```
npx hardhat run scripts/deploy.ts --network polygon_testnet
npx hardhat deploy --network polygon_testnet
```

Once the deployment completes, let's locate our contract on PolygonScan.
Expand Down
10 changes: 7 additions & 3 deletions contracts/CryptoBooks.sol
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
Expand All @@ -25,21 +25,25 @@ contract CryptoBooks is ERC721URIStorage, VRFConsumerBase {
mapping(bytes32 => address) public requestToSender;
mapping(bytes32 => uint256) public requestToTokenId;

event RequestedRandomness(bytes32 requestId);

constructor(
address _VRFCoordinator,
address _LinkToken,
bytes32 _keyHash
bytes32 _keyHash,
uint256 _chainlinkFee
) VRFConsumerBase(_VRFCoordinator, _LinkToken) ERC721("BookNFT", "BOOK") {
vrfCoordinator = _VRFCoordinator;
keyHash = _keyHash;
fee = 0.1 * 10**18; //0.1 LINK
fee = _chainlinkFee;
}

function requestNewRandomBook(string memory name, string memory author)
public
returns (bytes32)
{
bytes32 requestId = requestRandomness(keyHash, fee);
emit RequestedRandomness(requestId);
requestToBookName[requestId] = name;
requestToAuthorName[requestId] = author;
requestToSender[requestId] = msg.sender;
Expand Down
4 changes: 4 additions & 0 deletions contracts/test/LinkToken.sol
@@ -0,0 +1,4 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.24;

import "@chainlink/token/contracts/v0.4/LinkToken.sol";
4 changes: 4 additions & 0 deletions contracts/test/VRFCoordinatorMock.sol
@@ -0,0 +1,4 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/tests/VRFCoordinatorMock.sol";
33 changes: 33 additions & 0 deletions deploy/00_Deploy_Mocks.ts
@@ -0,0 +1,33 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";

const deployMocks: DeployFunction = async function (
hre: HardhatRuntimeEnvironment
) {
const { deployments, getNamedAccounts, getChainId } = hre;
const { deploy, log } = deployments;
const { deployer } = await getNamedAccounts();
const chainId = await getChainId();

// If this is to the local chain
if (chainId === "31337") {
log("Local network detected - Deploying mocks");

// Deploy LINK token to our local network
const LinkToken = await deploy("LinkToken", {
from: deployer,
log: true,
});

// Deploy a mock VRF Coordinator to our local network
await deploy("VRFCoordinatorMock", {
from: deployer,
log: true,
args: [LinkToken.address],
});

log("Mocks deployed");
}
};
export default deployMocks;
deployMocks.tags = ["all", "mocks"];
38 changes: 38 additions & 0 deletions deploy/01_Deploy_CryptoBooks.ts
@@ -0,0 +1,38 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { Deployment } from "hardhat-deploy/dist/types";
import { networkConfig } from "../helper-hardhat-config";

const deployCryptoBooks: DeployFunction = async function (
hre: HardhatRuntimeEnvironment
) {
const { deployments, getNamedAccounts, getChainId } = hre;
const { deploy, get } = deployments;
const { deployer } = await getNamedAccounts();
const chainId = await getChainId();

let linkTokenAddress: string | undefined;
let vrfCoordinatorAddress: string | undefined;
let LinkToken: Deployment;
let VRFCoordinatorMock: Deployment;

if (chainId === "31337") {
LinkToken = await get("LinkToken");
VRFCoordinatorMock = await get("VRFCoordinatorMock");
linkTokenAddress = LinkToken.address;
vrfCoordinatorAddress = VRFCoordinatorMock.address;
} else {
linkTokenAddress = networkConfig[chainId].linkToken;
vrfCoordinatorAddress = networkConfig[chainId].vrfCoordinator;
}

const keyHash: string = networkConfig[chainId].keyHash;
const chainlinkFee: string = networkConfig[chainId].chainlinkFee;
await deploy("CryptoBooks", {
from: deployer,
args: [vrfCoordinatorAddress, linkTokenAddress, keyHash, chainlinkFee],
log: true,
});
};
export default deployCryptoBooks;
deployCryptoBooks.tags = ["all", "books"];
22 changes: 21 additions & 1 deletion hardhat.config.ts
@@ -1,9 +1,11 @@
import * as dotenv from "dotenv";

import { HardhatUserConfig, task } from "hardhat/config";
import "@appliedblockchain/chainlink-plugins-fund-link";
import "@nomiclabs/hardhat-etherscan";
import "@nomiclabs/hardhat-waffle";
import "@typechain/hardhat";
import "hardhat-deploy";
import "hardhat-gas-reporter";
import "solidity-coverage";

Expand All @@ -18,7 +20,19 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
});

const config: HardhatUserConfig = {
solidity: "0.8.9",
solidity: {
compilers: [
{
version: "0.8.7",
},
{
version: "0.6.6",
},
{
version: "0.4.24",
},
],
},
networks: {
polygon_testnet: {
url: "https://rpc-mumbai.maticvigil.com",
Expand All @@ -33,6 +47,12 @@ const config: HardhatUserConfig = {
etherscan: {
apiKey: { polygonMumbai: process.env.POLYGON_SCAN_API_KEY },
},
namedAccounts: {
deployer: {
default: 0,
1: 0,
},
},
};

export default config;
36 changes: 36 additions & 0 deletions helper-hardhat-config.ts
@@ -0,0 +1,36 @@
export interface networkConfigItem {
name: string;
chainlinkFee: string;
keyHash: string;
linkToken?: string;
vrfCoordinator?: string;
}

export interface networkConfigInfo {
[key: string]: networkConfigItem;
}

export const networkConfig: networkConfigInfo = {
default: {
name: "hardhat",
chainlinkFee: "100000000000000000",
keyHash:
"0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4",
},
31337: {
name: "localhost",
chainlinkFee: "100000000000000000",
keyHash:
"0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4",
},
80001: {
name: "polygon_testnet",
linkToken: "0x326C977E6efc84E512bB9C30f76E30c160eD06FB",
keyHash:
"0x6e75b569a01ef56d18cab6a8e71e6600d6ce853834d4a5748b720d06f878b3a4",
vrfCoordinator: "0x8C7382F9D8f56b33781fE506E897a4F1e2d17255",
chainlinkFee: "100000000000000000",
},
};

export const developmentChains = ["hardhat", "localhost"];

0 comments on commit b60b1c4

Please sign in to comment.