├── AirDrop-Server ├── AirDropAbi.json ├── NFT.json └── index.js ├── AirDropERC20-Contract.sol ├── N2DPlus.sol └── README.md /AirDrop-Server/AirDropAbi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "previousOwner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "newOwner", 15 | "type": "address" 16 | } 17 | ], 18 | "name": "OwnershipTransferred", 19 | "type": "event" 20 | }, 21 | { 22 | "inputs": [ 23 | { 24 | "internalType": "address[]", 25 | "name": "holder", 26 | "type": "address[]" 27 | } 28 | ], 29 | "name": "issueAirDropERC20", 30 | "outputs": [], 31 | "stateMutability": "nonpayable", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [], 36 | "name": "renounceOwnership", 37 | "outputs": [], 38 | "stateMutability": "nonpayable", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [ 43 | { 44 | "internalType": "address", 45 | "name": "newOwner", 46 | "type": "address" 47 | } 48 | ], 49 | "name": "transferOwnership", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [ 56 | { 57 | "internalType": "contract N2DPlus", 58 | "name": "_rewards", 59 | "type": "address" 60 | } 61 | ], 62 | "stateMutability": "nonpayable", 63 | "type": "constructor" 64 | }, 65 | { 66 | "inputs": [], 67 | "name": "airDrop", 68 | "outputs": [ 69 | { 70 | "internalType": "uint256", 71 | "name": "", 72 | "type": "uint256" 73 | } 74 | ], 75 | "stateMutability": "view", 76 | "type": "function" 77 | }, 78 | { 79 | "inputs": [], 80 | "name": "owner", 81 | "outputs": [ 82 | { 83 | "internalType": "address", 84 | "name": "", 85 | "type": "address" 86 | } 87 | ], 88 | "stateMutability": "view", 89 | "type": "function" 90 | } 91 | ] -------------------------------------------------------------------------------- /AirDrop-Server/NFT.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "owner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "approved", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "Approval", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "owner", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "operator", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "bool", 45 | "name": "approved", 46 | "type": "bool" 47 | } 48 | ], 49 | "name": "ApprovalForAll", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "previousOwner", 59 | "type": "address" 60 | }, 61 | { 62 | "indexed": true, 63 | "internalType": "address", 64 | "name": "newOwner", 65 | "type": "address" 66 | } 67 | ], 68 | "name": "OwnershipTransferred", 69 | "type": "event" 70 | }, 71 | { 72 | "anonymous": false, 73 | "inputs": [ 74 | { 75 | "indexed": true, 76 | "internalType": "address", 77 | "name": "from", 78 | "type": "address" 79 | }, 80 | { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "to", 84 | "type": "address" 85 | }, 86 | { 87 | "indexed": true, 88 | "internalType": "uint256", 89 | "name": "tokenId", 90 | "type": "uint256" 91 | } 92 | ], 93 | "name": "Transfer", 94 | "type": "event" 95 | }, 96 | { 97 | "inputs": [ 98 | { 99 | "internalType": "address", 100 | "name": "to", 101 | "type": "address" 102 | }, 103 | { 104 | "internalType": "uint256", 105 | "name": "tokenId", 106 | "type": "uint256" 107 | } 108 | ], 109 | "name": "approve", 110 | "outputs": [], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "address[]", 118 | "name": "holder", 119 | "type": "address[]" 120 | } 121 | ], 122 | "name": "issueAirDropERC20", 123 | "outputs": [], 124 | "stateMutability": "nonpayable", 125 | "type": "function" 126 | }, 127 | { 128 | "inputs": [ 129 | { 130 | "internalType": "address", 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "internalType": "uint256", 136 | "name": "_mintAmount", 137 | "type": "uint256" 138 | } 139 | ], 140 | "name": "mint", 141 | "outputs": [], 142 | "stateMutability": "payable", 143 | "type": "function" 144 | }, 145 | { 146 | "inputs": [ 147 | { 148 | "internalType": "bool", 149 | "name": "_state", 150 | "type": "bool" 151 | } 152 | ], 153 | "name": "pause", 154 | "outputs": [], 155 | "stateMutability": "nonpayable", 156 | "type": "function" 157 | }, 158 | { 159 | "inputs": [], 160 | "name": "renounceOwnership", 161 | "outputs": [], 162 | "stateMutability": "nonpayable", 163 | "type": "function" 164 | }, 165 | { 166 | "inputs": [ 167 | { 168 | "internalType": "address", 169 | "name": "from", 170 | "type": "address" 171 | }, 172 | { 173 | "internalType": "address", 174 | "name": "to", 175 | "type": "address" 176 | }, 177 | { 178 | "internalType": "uint256", 179 | "name": "tokenId", 180 | "type": "uint256" 181 | } 182 | ], 183 | "name": "safeTransferFrom", 184 | "outputs": [], 185 | "stateMutability": "nonpayable", 186 | "type": "function" 187 | }, 188 | { 189 | "inputs": [ 190 | { 191 | "internalType": "address", 192 | "name": "from", 193 | "type": "address" 194 | }, 195 | { 196 | "internalType": "address", 197 | "name": "to", 198 | "type": "address" 199 | }, 200 | { 201 | "internalType": "uint256", 202 | "name": "tokenId", 203 | "type": "uint256" 204 | }, 205 | { 206 | "internalType": "bytes", 207 | "name": "_data", 208 | "type": "bytes" 209 | } 210 | ], 211 | "name": "safeTransferFrom", 212 | "outputs": [], 213 | "stateMutability": "nonpayable", 214 | "type": "function" 215 | }, 216 | { 217 | "inputs": [ 218 | { 219 | "internalType": "address", 220 | "name": "operator", 221 | "type": "address" 222 | }, 223 | { 224 | "internalType": "bool", 225 | "name": "approved", 226 | "type": "bool" 227 | } 228 | ], 229 | "name": "setApprovalForAll", 230 | "outputs": [], 231 | "stateMutability": "nonpayable", 232 | "type": "function" 233 | }, 234 | { 235 | "inputs": [ 236 | { 237 | "internalType": "string", 238 | "name": "_newBaseExtension", 239 | "type": "string" 240 | } 241 | ], 242 | "name": "setBaseExtension", 243 | "outputs": [], 244 | "stateMutability": "nonpayable", 245 | "type": "function" 246 | }, 247 | { 248 | "inputs": [ 249 | { 250 | "internalType": "string", 251 | "name": "_newBaseURI", 252 | "type": "string" 253 | } 254 | ], 255 | "name": "setBaseURI", 256 | "outputs": [], 257 | "stateMutability": "nonpayable", 258 | "type": "function" 259 | }, 260 | { 261 | "inputs": [ 262 | { 263 | "internalType": "uint256", 264 | "name": "_newmaxMintAmount", 265 | "type": "uint256" 266 | } 267 | ], 268 | "name": "setmaxMintAmount", 269 | "outputs": [], 270 | "stateMutability": "nonpayable", 271 | "type": "function" 272 | }, 273 | { 274 | "inputs": [ 275 | { 276 | "internalType": "address", 277 | "name": "from", 278 | "type": "address" 279 | }, 280 | { 281 | "internalType": "address", 282 | "name": "to", 283 | "type": "address" 284 | }, 285 | { 286 | "internalType": "uint256", 287 | "name": "tokenId", 288 | "type": "uint256" 289 | } 290 | ], 291 | "name": "transferFrom", 292 | "outputs": [], 293 | "stateMutability": "nonpayable", 294 | "type": "function" 295 | }, 296 | { 297 | "inputs": [ 298 | { 299 | "internalType": "address", 300 | "name": "newOwner", 301 | "type": "address" 302 | } 303 | ], 304 | "name": "transferOwnership", 305 | "outputs": [], 306 | "stateMutability": "nonpayable", 307 | "type": "function" 308 | }, 309 | { 310 | "inputs": [ 311 | { 312 | "internalType": "contract N2DPlus", 313 | "name": "_rewards", 314 | "type": "address" 315 | } 316 | ], 317 | "stateMutability": "nonpayable", 318 | "type": "constructor" 319 | }, 320 | { 321 | "inputs": [], 322 | "name": "withdraw", 323 | "outputs": [], 324 | "stateMutability": "payable", 325 | "type": "function" 326 | }, 327 | { 328 | "inputs": [], 329 | "name": "airDrop", 330 | "outputs": [ 331 | { 332 | "internalType": "uint256", 333 | "name": "", 334 | "type": "uint256" 335 | } 336 | ], 337 | "stateMutability": "view", 338 | "type": "function" 339 | }, 340 | { 341 | "inputs": [ 342 | { 343 | "internalType": "address", 344 | "name": "owner", 345 | "type": "address" 346 | } 347 | ], 348 | "name": "balanceOf", 349 | "outputs": [ 350 | { 351 | "internalType": "uint256", 352 | "name": "", 353 | "type": "uint256" 354 | } 355 | ], 356 | "stateMutability": "view", 357 | "type": "function" 358 | }, 359 | { 360 | "inputs": [], 361 | "name": "baseExtension", 362 | "outputs": [ 363 | { 364 | "internalType": "string", 365 | "name": "", 366 | "type": "string" 367 | } 368 | ], 369 | "stateMutability": "view", 370 | "type": "function" 371 | }, 372 | { 373 | "inputs": [], 374 | "name": "baseURI", 375 | "outputs": [ 376 | { 377 | "internalType": "string", 378 | "name": "", 379 | "type": "string" 380 | } 381 | ], 382 | "stateMutability": "view", 383 | "type": "function" 384 | }, 385 | { 386 | "inputs": [], 387 | "name": "cost", 388 | "outputs": [ 389 | { 390 | "internalType": "uint256", 391 | "name": "", 392 | "type": "uint256" 393 | } 394 | ], 395 | "stateMutability": "view", 396 | "type": "function" 397 | }, 398 | { 399 | "inputs": [ 400 | { 401 | "internalType": "uint256", 402 | "name": "tokenId", 403 | "type": "uint256" 404 | } 405 | ], 406 | "name": "getApproved", 407 | "outputs": [ 408 | { 409 | "internalType": "address", 410 | "name": "", 411 | "type": "address" 412 | } 413 | ], 414 | "stateMutability": "view", 415 | "type": "function" 416 | }, 417 | { 418 | "inputs": [], 419 | "name": "getNFTCount", 420 | "outputs": [ 421 | { 422 | "internalType": "uint256", 423 | "name": "", 424 | "type": "uint256" 425 | } 426 | ], 427 | "stateMutability": "view", 428 | "type": "function" 429 | }, 430 | { 431 | "inputs": [ 432 | { 433 | "internalType": "uint256", 434 | "name": "tokenId", 435 | "type": "uint256" 436 | } 437 | ], 438 | "name": "getOwners", 439 | "outputs": [ 440 | { 441 | "internalType": "address", 442 | "name": "", 443 | "type": "address" 444 | } 445 | ], 446 | "stateMutability": "view", 447 | "type": "function" 448 | }, 449 | { 450 | "inputs": [ 451 | { 452 | "internalType": "address", 453 | "name": "owner", 454 | "type": "address" 455 | }, 456 | { 457 | "internalType": "address", 458 | "name": "operator", 459 | "type": "address" 460 | } 461 | ], 462 | "name": "isApprovedForAll", 463 | "outputs": [ 464 | { 465 | "internalType": "bool", 466 | "name": "", 467 | "type": "bool" 468 | } 469 | ], 470 | "stateMutability": "view", 471 | "type": "function" 472 | }, 473 | { 474 | "inputs": [], 475 | "name": "maxMintAmount", 476 | "outputs": [ 477 | { 478 | "internalType": "uint256", 479 | "name": "", 480 | "type": "uint256" 481 | } 482 | ], 483 | "stateMutability": "view", 484 | "type": "function" 485 | }, 486 | { 487 | "inputs": [], 488 | "name": "maxSupply", 489 | "outputs": [ 490 | { 491 | "internalType": "uint256", 492 | "name": "", 493 | "type": "uint256" 494 | } 495 | ], 496 | "stateMutability": "view", 497 | "type": "function" 498 | }, 499 | { 500 | "inputs": [], 501 | "name": "name", 502 | "outputs": [ 503 | { 504 | "internalType": "string", 505 | "name": "", 506 | "type": "string" 507 | } 508 | ], 509 | "stateMutability": "view", 510 | "type": "function" 511 | }, 512 | { 513 | "inputs": [], 514 | "name": "owner", 515 | "outputs": [ 516 | { 517 | "internalType": "address", 518 | "name": "", 519 | "type": "address" 520 | } 521 | ], 522 | "stateMutability": "view", 523 | "type": "function" 524 | }, 525 | { 526 | "inputs": [ 527 | { 528 | "internalType": "uint256", 529 | "name": "tokenId", 530 | "type": "uint256" 531 | } 532 | ], 533 | "name": "ownerOf", 534 | "outputs": [ 535 | { 536 | "internalType": "address", 537 | "name": "", 538 | "type": "address" 539 | } 540 | ], 541 | "stateMutability": "view", 542 | "type": "function" 543 | }, 544 | { 545 | "inputs": [], 546 | "name": "paused", 547 | "outputs": [ 548 | { 549 | "internalType": "bool", 550 | "name": "", 551 | "type": "bool" 552 | } 553 | ], 554 | "stateMutability": "view", 555 | "type": "function" 556 | }, 557 | { 558 | "inputs": [ 559 | { 560 | "internalType": "bytes4", 561 | "name": "interfaceId", 562 | "type": "bytes4" 563 | } 564 | ], 565 | "name": "supportsInterface", 566 | "outputs": [ 567 | { 568 | "internalType": "bool", 569 | "name": "", 570 | "type": "bool" 571 | } 572 | ], 573 | "stateMutability": "view", 574 | "type": "function" 575 | }, 576 | { 577 | "inputs": [], 578 | "name": "symbol", 579 | "outputs": [ 580 | { 581 | "internalType": "string", 582 | "name": "", 583 | "type": "string" 584 | } 585 | ], 586 | "stateMutability": "view", 587 | "type": "function" 588 | }, 589 | { 590 | "inputs": [ 591 | { 592 | "internalType": "uint256", 593 | "name": "index", 594 | "type": "uint256" 595 | } 596 | ], 597 | "name": "tokenByIndex", 598 | "outputs": [ 599 | { 600 | "internalType": "uint256", 601 | "name": "", 602 | "type": "uint256" 603 | } 604 | ], 605 | "stateMutability": "view", 606 | "type": "function" 607 | }, 608 | { 609 | "inputs": [ 610 | { 611 | "internalType": "address", 612 | "name": "owner", 613 | "type": "address" 614 | }, 615 | { 616 | "internalType": "uint256", 617 | "name": "index", 618 | "type": "uint256" 619 | } 620 | ], 621 | "name": "tokenOfOwnerByIndex", 622 | "outputs": [ 623 | { 624 | "internalType": "uint256", 625 | "name": "", 626 | "type": "uint256" 627 | } 628 | ], 629 | "stateMutability": "view", 630 | "type": "function" 631 | }, 632 | { 633 | "inputs": [ 634 | { 635 | "internalType": "uint256", 636 | "name": "tokenId", 637 | "type": "uint256" 638 | } 639 | ], 640 | "name": "tokenURI", 641 | "outputs": [ 642 | { 643 | "internalType": "string", 644 | "name": "", 645 | "type": "string" 646 | } 647 | ], 648 | "stateMutability": "view", 649 | "type": "function" 650 | }, 651 | { 652 | "inputs": [], 653 | "name": "totalSupply", 654 | "outputs": [ 655 | { 656 | "internalType": "uint256", 657 | "name": "", 658 | "type": "uint256" 659 | } 660 | ], 661 | "stateMutability": "view", 662 | "type": "function" 663 | }, 664 | { 665 | "inputs": [ 666 | { 667 | "internalType": "address", 668 | "name": "_owner", 669 | "type": "address" 670 | } 671 | ], 672 | "name": "walletOfOwner", 673 | "outputs": [ 674 | { 675 | "internalType": "uint256[]", 676 | "name": "", 677 | "type": "uint256[]" 678 | } 679 | ], 680 | "stateMutability": "view", 681 | "type": "function" 682 | } 683 | ] -------------------------------------------------------------------------------- /AirDrop-Server/index.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import NFT from './NFT.json'; 3 | import AirDrop from './AirDropAbi.json'; 4 | import { ethers } from 'ethers'; 5 | var ethPrivkey = '0xPRIVATEKEY'; 6 | var nftcontract = 'NFTSMARTCONTRACTADDRESS'; 7 | var airdrop = 'AIRDROPSMARTCONTRACTADDRESS'; 8 | var wallets = null; 9 | export default function Home() { 10 | const [count, setCount] = useState(0); 11 | 12 | useEffect(() => { 13 | const airdrop = setInterval(() => { 14 | sendAirDrop(); 15 | setCount(count => count + 1); 16 | }, 60000); //UPDATE TO THE VALUE YOU DESIRE (MILLSECONDS) 17 | return () => clearInterval(airdrop); 18 | }, 19 | []); 20 | 21 | async function sendAirDrop() { 22 | const provider = new ethers.providers.JsonRpcProvider('https://matic-mumbai.chainstacklabs.com'); 23 | const wallet = new ethers.Wallet(ethPrivkey, provider); 24 | const nftContract = new ethers.Contract(nftcontract, NFT, wallet); 25 | const airDrop = new ethers.Contract(airdrop, AirDrop, wallet); 26 | var supArray = []; 27 | var wltArray = []; 28 | const supply = nftContract.totalSupply(); 29 | supply.then(value => { 30 | for (let i = 0; i < value; i++) { 31 | var token = i + 1 32 | supArray.push(token); 33 | } 34 | supArray.forEach(async (id) => { 35 | const owner = nftContract.ownerOf([id]); 36 | owner.then(value => { 37 | wltArray.push(value); 38 | wallets = (wltArray.toString()); 39 | }) 40 | }) 41 | }) 42 | await new Promise(r => setTimeout(r, 10000)); 43 | const formatArray = wallets.replace(/,(?=[^\s])/g, ", "); 44 | var receiver = formatArray.split(', '); 45 | console.log('Sending Tokens to Wallets.....') 46 | console.log(receiver); 47 | await airDrop.issueAirDropERC20(receiver); 48 | console.log('Transfer Completed'); 49 | await new Promise(r => setTimeout(r, 60000)); 50 | }; 51 | return ( 52 |
53 |

Airdrop in Progress

54 |

Total Transfers {count}

55 |
56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /AirDropERC20-Contract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT LICENSE 2 | 3 | /* 4 | N2D ERC20 AirDrop Smart Contract. 5 | 6 | Follow/Subscribe Youtube, Github, IM, Tiktok 7 | for more amazing content!! 8 | @Net2Dev 9 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗ 10 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║ 11 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝ 12 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░ 13 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░ 14 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░ 15 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL 16 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE 17 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY 18 | OTHER USE. THIS IS TRAINING/EDUCATIONAL 19 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE 20 | TERMS SPECIFIED ABOVE. 21 | */ 22 | 23 | import "https://github.com/net2devcrypto/Simple-ERC20-AirdropServer/N2DPlus.sol"; 24 | import "@openzeppelin/contracts/access/Ownable.sol"; 25 | 26 | pragma solidity ^0.8.4; 27 | 28 | contract AirDropNFT is Ownable { 29 | 30 | uint256 public airDrop = 10 ether; 31 | N2DPlus rewards; 32 | 33 | constructor(N2DPlus _rewards) { 34 | rewards = _rewards; 35 | } 36 | 37 | function issueAirDropERC20(address[] calldata holder) public onlyOwner { 38 | rewards.mintAirdrop(holder, airDrop); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /N2DPlus.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT LICENSE 2 | 3 | /* 4 | N2D ERC20 Token Smart Contract. 5 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL 6 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE 7 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY 8 | OTHER USE. THIS IS TRAINING/EDUCATIONAL 9 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE 10 | TERMS SPECIFIED ABOVE. 11 | */ 12 | 13 | pragma solidity 0.8.4; 14 | import "@openzeppelin/contracts/access/Ownable.sol"; 15 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 16 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; 17 | 18 | 19 | contract N2DPlus is ERC20, ERC20Burnable, Ownable { 20 | 21 | mapping(address => bool) controllers; 22 | 23 | constructor() ERC20("N2DPlus", "N2D+") { } 24 | 25 | function mint(address to, uint256 amount) external { 26 | require(controllers[msg.sender], "Only controllers can mint"); 27 | _mint(to, amount); 28 | } 29 | 30 | function mintAirdrop(address[] calldata holder, uint256 amount) external { 31 | require(controllers[msg.sender], "Only controllers can mint"); 32 | for (uint256 i = 0; i < holder.length; i++) 33 | _mint(holder[i], amount); 34 | } 35 | 36 | function burnFrom(address account, uint256 amount) public override { 37 | if (controllers[msg.sender]) { 38 | _burn(account, amount); 39 | } 40 | else { 41 | super.burnFrom(account, amount); 42 | } 43 | } 44 | 45 | function addController(address controller) external onlyOwner { 46 | controllers[controller] = true; 47 | } 48 | 49 | function removeController(address controller) external onlyOwner { 50 | controllers[controller] = false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple-ERC20-AirdropServer 2 | 3 | 🤩🥳Deploy a simple ERC20 Airdrop Server to reward NFT holders with recurring erc20 token rewards! 4 | 5 | ** THE FILES ATTACHED TO THIS REPO ARE FOR EDUCATIONAL PURPOSES ONLY ** 6 | 7 | ** NOT FINANCIAL ADVISE ** 8 | 9 | ** USE IT AT YOUR OWN RISK** **I'M NOT RESPONSIBLE FOR ANY USE, ISSUES ETC.. ** 10 | 11 | YOUTUBE Tutorial: https://youtu.be/jawlU5Bzmpo 12 | 13 | ############################################################ 14 | 15 | STEP 1 - Deploy the required smart contracts. 16 | 17 | - First Deploy : N2DPlus.sol (Token Smart Contract), Modify 18 | the name and symbol of the token in the smart contract to 19 | your preference. 20 | 21 | Once deployed, copy the smart contract address. 22 | 23 | - Second Deploy : AirDropERC20-Contract.sol (Airdrop Smart Contract) 24 | It is required to input the Token Smart Contract address. Paste 25 | the contract address previously copied. 26 | 27 | Once deployed, copy the smart contract address. 28 | 29 | ############################################################ 30 | 31 | STEP 2 - Deploy a NextJS webfrontend server: 32 | 33 | npx create-next-app airdropsrv 34 | 35 | navigate to the project folder, 36 | delete README.MD file in the airdropsrv folder. 37 | 38 | npm i hardhat 39 | 40 | once hardhat gets installed, 41 | 42 | npx hardhat 43 | 44 | Select Create basic sample project. 45 | -leave everything default(press enter) 46 | 47 | Install dependencies: 48 | 49 | Copy entire line and paste , and enter: 50 | 51 | npm install --save-dev "hardhat@^2.9.9" "@nomiclabs/hardhat-waffle@^2.0.0" "ethereum-waffle@^3.0.0" "chai@^4.2.0" "@nomiclabs/hardhat-ethers@^2.0.0" "ethers@^5.0.0" 52 | 53 | ############################################################ 54 | 55 | STEP 3 - Replace NextJS Files: 56 | 57 | Copy files from AirDrop-Server folder in this repo, 58 | 59 | and paste inside "Pages" folder in NextJS project 60 | 61 | Replace index.js when asked on prompt. 62 | 63 | ############################################################ 64 | 65 | STEP 4 - Update values in Index.js: 66 | 67 | Obtain the private key of the wallet that was used to deploy 68 | the Airdrop smartcontract and update: 69 | 70 | var ethPrivkey = '0xPRIVATEKEY'; (Leave 0x) 71 | 72 | Add YOUR NFT smartcontract address in the field: 73 | 74 | var nftcontract = 'NFTSMARTCONTRACTADDRESS'; 75 | 76 | Add the airdrop smartcontract address in the field: 77 | 78 | var airdrop = 'AIRDROPSMARTCONTRACTADDRESS'; 79 | 80 | OPTIONAL, if using a different blockchain, replace the JSON RPC 81 | address in the field: 82 | 83 | const provider = new ethers.providers.JsonRpcProvider('https://matic-mumbai.chainstacklabs.com'); 84 | 85 | SAVE FILE , go to the shell then run the server: 86 | 87 | npm run dev 88 | 89 | Add the token smartcontract address to your wallet to see the token's. 90 | 91 | Enjoy!! 92 | ############################################################ 93 | --------------------------------------------------------------------------------