A Dutch auction is a type of an auction in which the initial price of an NFT starts at its ceiling and lowers by a small amount at set intervals. Buyers make bids at reduced prices until the end of an auction. A Dutch auction continues until either all assets are sold out or the auction time ends.The objective of this tutorial is to familiarize you with the Cronos network, Hardhat, and Dutch auction smart contracts. In the end of the tutorial, you will be able to create a simple Dutch auction smart contract to help you sell your NFTs to the highest bidder.Specifically, in this tutorial, you will:
Create a Dutch auction smart contract.
Deploy and verify the contract on Cronos Mainnet through a node deployed with Chainstack.
In your project directory, run npx hardhat. Select Create a JavaScript project and agree to install the sample project’s dependencies. This will create a sample project directory with a smart contract draft.
To complete the project, we need to install several additional dependencies.The OpenZeppelin Contract library allows you to inherit smart contracts. To install it, run:
npm i @openzeppelin/contracts
The dotenv library allows you to export and keep sensitive data securely. To install it, run:
npm i dotenv
Contract verification uses @nomicfoundation/hardhat-verify, which is already bundled in the @nomicfoundation/hardhat-toolbox the sample project installed — no separate verification plugin is needed. You point it at the Cronos Explorer in the Hardhat config below.You need to create an environment file to store your sensitive data with the project. To create it, in your project directory, run:
Navigate to your previously created project directory and go to the contracts directory. In the directory, create your Dutch auction smart contract: DutchAuction.sol.
// SPDX-License-Identifier: MITpragma solidity ^0.8.0;import "@openzeppelin/contracts/token/ERC721/ERC721.sol";import "@openzeppelin/contracts/access/Ownable.sol";import "@openzeppelin/contracts/utils/Counters.sol";contract MyToken is ERC721, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIdCounter; uint256 public immutable startPrice = 10 ether; uint256 public immutable startAt; uint256 public immutable endsAt; uint256 public immutable endPrice = 5 ether; uint256 public immutable discountRate = 0.01 ether; uint256 public duration = 500 minutes; uint256 public immutable MAX_SUPPLY = 100; mapping (address => bool) public onlyOne; constructor() ERC721("CronosNFT", "CroNFT") { startAt = block.timestamp; endsAt = block.timestamp + duration; } function price() public view returns (uint256) { if (block.timestamp > endsAt ) { return endPrice; } uint256 minutesElapsed = (block.timestamp - startAt) / 60; return startPrice - (minutesElapsed * discountRate); } function safeMint(address to) public payable { require(msg.value >= price(), "Not enough ether sent"); require(!onlyOne[msg.sender], "Sorry, Address already has 1 NFT!"); uint256 tokenId = _tokenIdCounter.current(); require(tokenId < MAX_SUPPLY, "No more items left."); _safeMint(to, tokenId + 1); _tokenIdCounter.increment(); onlyOne[msg.sender]=true; } function withdraw() public onlyOwner { payable(owner()).transfer(address(this).balance); }}
The contract implementation is the following:
The price of an NFT starts at 10 ether and decreases to 5 ether over 500 minutes. A maximum of 100 NFTs can be minted.
The contract uses the onlyOne mapping to ensure that each address can only own one NFT from your collection.
The contract sets the values of the start and end price, which cannot be changed later on.
The function price() uses block.timestamp to calculate the price of an NFT each time the safeMint function is called.
If all the required conditions are satisfied, the wallet address gets an NFT minted.
To compile the contract, in your project directory, run:
To deploy your smart contract on Cronos Mainnet, the deploying wallet needs CRO to cover gas. Fund it with a small amount of CRO from an exchange or an existing wallet.
This tutorial guided you through the basics of using Hardhat to deploy a Dutch auction smart contract to Cronos Mainnet, and verify it against the Cronos Explorer with hardhat-verify.Because this deploys to Cronos Mainnet, every deployment and mint spends real CRO — keep amounts small while you experiment.