A blockchain-based system for creating and managing dynamic NFTs that represent real-time weather conditions. The NFTs automatically update their metadata based on weather data provided through a decentralized oracle system.
- Features
- Architecture
- Tech Stack
- Getting Started
- Deployment Guide
- Contract Interaction
- Testing
- Test Coverage
- Dynamic NFTs that update based on weather conditions
- Decentralized oracle system for weather data
- Factory pattern for easy NFT collection deployment
- Comprehensive testing suite
- Gas-optimized contract implementations
- Role-based access control
- Automated metadata updates
The system consists of three main components:
-
WeatherNFTFactory: Factory contract for deploying new WeatherNFT collections
- Handles creation and tracking of WeatherNFT instances
- Uses CREATE2 for deterministic addresses
- Maintains registry of deployed contracts
-
WeatherNFT: ERC721 contract with dynamic metadata
- Implements ERC721URIStorage for metadata management
- Stores weather data on-chain
- Updates metadata based on oracle input
- Enforces access control for updates
-
WeatherOracle: Oracle system for weather data
- Manages authorized data providers
- Enforces update intervals
- Validates and processes weather data
- Triggers NFT metadata updates
-
Smart Contract Development:
- Solidity ^0.8.28
- OpenZeppelin Contracts 5.x.x
-
Development Framework:
- Foundry
- Forge (testing)
- Cast (contract interaction)
- Anvil (local network)
-
Testing:
- Forge Test Suite
- Fuzz Testing
- Gas Usage Analysis
- Clone the repository:
git clone https://github.com/your-username/dynamic-weather-nft.git
cd dynamic-weather-nft- Install dependencies:
forge install- Copy the environment file:
cp .env.example .env- Set up your environment variables in
.env
forge build- Start local node:
anvil- Deploy Factory:
forge script script/DeployFactory.s.sol --rpc-url http://localhost:8545 --private-key $PRIVATE_KEY --broadcast- Deploy NFT:
export FACTORY_ADDRESS=<deployed-factory-address>
forge script script/DeployNFT.s.sol --rpc-url http://localhost:8545 --private-key $PRIVATE_KEY --broadcast- Deploy Oracle:
export NFT_ADDRESS=<deployed-nft-address>
export WEATHER_PROVIDER_ADDRESS=<provider-address>
forge script script/DeployOracle.s.sol --rpc-url http://localhost:8545 --private-key $PRIVATE_KEY --broadcast- Deploy Factory:
forge script script/DeployFactory.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify- Deploy NFT:
forge script script/DeployNFT.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify- Deploy Oracle (NOT WORKING YET):
forge script script/DeployOracle.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verifycast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $FACTORY_ADDRESS "deployWeatherNFT(string,string)" "Weather Collection" "WEATHER"cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $NFT_ADDRESS "safeMint(address,string)" $RECIPIENT_ADDRESS "ipfs://metadata-uri"cast send --rpc-url $RPC_URL --private-key $PROVIDER_KEY $ORACLE_ADDRESS "submitWeatherData(uint256,int256,uint256,uint256,string)" 1 "250000000000000000" "600000000000000000" "100000000000000000" "Sunny"Ran 36 tests (0 failed, 0 skipped)
| File | % Lines | % Statements | % Branches | % Funcs |
|---------------------------|-----------------|-----------------|---------------|-----------------|
| src/WeatherNFT.sol | 100.00% (17/17) | 100.00% (19/19) | 100.00% (3/3) | 100.00% (5/5) |
| src/WeatherNFTFactory.sol | 100.00% (19/19) | 95.65% (22/23) | 50.00% (1/2) | 100.00% (4/4) |
| src/WeatherOracle.sol | 93.94% (31/33) | 93.75% (30/32) | 66.67% (4/6) | 100.00% (6/6) |
| Total | 97.10% (67/69) | 95.95% (71/74) | 72.73% (8/11) | 100.00% (15/15) |
# Run all tests
forge test
# Run tests with gas reporting
forge test --gas-report
# Run specific test file
forge test --match-path test/WeatherNFT.t.sol
# Run with verbosity level
forge test -vvvv