Check it out live at https://tierchain.afcms.dev/
Make sure the world knows your outreageous hot takes are yours. Use TierChain. Powered by Etherium (on Sepolia test network).
The owner can define tier lists and items for them.
Users can post and secure their tier lists.
The provided UI allows making and posting a tier list, and can also use provided images in place of the normal names.
- Hardhat 3 for smart contract development, local test chain and deployment scripts.
- React, Tailwind CSS and daisyUI for the frontend, with Vite as the build tool.
- Wagmi for Ethereum wallet integration in the frontend.
- Alchemy for Ethereum node access, used in the frontend to interact with the smart contract.
- Sepolia test network for deploying the smart contract in a live environment without using real Ethereum.
Clone the repo :
https://github.com/AFCMS/tierchain.gitInstall dependencies :
pnpm installBuild the contract :
pnpm run build:contractThis will create the directory artifacts/, which, among other things, contains the abi.
Start hardat :
pnpm hardhat nodeOf course, leave this running as long as you are using or developping.
Take an account in there, and set HARDHAT_PRIVATE_KEY in your .env to it’s private key, visible in the output.
Deploy the contract (Hardhat node) :
pnpm hardhat ignition deploy ignition/modules/TierList.ts --network localhostNote you will need to restart hardhat and redeploy the contract every time you change the contract. Hardhat tries to keep the same addresses, but double-check if something goes wrong. In your .env, set VITE_CONTRACT_TIERLIST_ADDRESS to the outputted address.
Deploy the contract (Sepolia) :
pnpm hardhat ignition deploy ignition/modules/TierList.ts --network sepoliaPopulate the tier lists :
node ./scripts/tierlist-manager.ts create --file ./tierlists/which-browser-is-the-best.json --mode hardhatThe script doesn’t yet have a « populate all » option, so for now, use a shell loop.
Run in dev mode :
pnpm run devBuild and run :
pnpm run buildRun tests :
pnpm hardhat testThe contract is located at contracts/TierList.sol, along with it’s tests.
For the data it holds, please consult it, a text explaination would not be any clearer, even for the unfamiliar with the self-explanatory solidity syntax.
Events are emitted when a Tier List is created, it’s active status changes, a user submits a new ranking, and when items are added or removed from tier lists.
There is one user function, submitRanking, which, you guessed it, submits a ranking.
Views to be used by frontends are :
- getTierLists(none) : returns all the tier lists currently available
- getTierList(tlId uint256) : returns information about a tier list by it’s id
- getTierListItems(tlId uint256) : returns the items a tier list has for ranking
- getUserVotes(tlId uint256, address user) : returns the ranking of a user for a tier list
- getItemVoteCounts(tlId uint256, itemId uint256) : returns the aggregate of votes for an item of a tier list
- getLatestSubmissions(tlId uint256, limit uint256, offset uint256) : returns a slice of user rankings for a tier list in reverse chronological order. Supports pagination with limit and offset.
Constraints :
- each user can only have one ranking per tier list
- items of a tier list are unique
- rankings are formed correctly, this means : 5 tiers, containing valid items. Items can be left in the pool. For gas economy, we chose to disable enforcing each item be unique within a ranking, but it can be enabled (see line 239 of TierList.sol).
Made with ❤️ by AFCMS & AKArien
Ecole Hexagone 🇫🇷 - Class of 2025/2026