diff --git a/.env b/.env index b27c62e5..e9d20e73 100644 --- a/.env +++ b/.env @@ -8,4 +8,7 @@ moralisApiSecret = xxxxxxx frpcPath = F:\frpc\frpc.exe chain = ganache moralisSubdomain = xxxxxxx.usemoralis.com -abiPath = "F:\ethereum-boilerplate\Truffle\build\contracts\Contract.json" \ No newline at end of file +abiPath = "F:\ethereum-boilerplate\Truffle\build\contracts\Contract.json" + +alchemy_api_url: https://eth-rinkeby.alchemyapi.io/v2/gQUHfEyfP_v73J37inUmWzPnYN0nOLr_ +rinkeby_key: a7a2f59191ce8477761f043f9da63a40ced24f803fd6a423930585e981ef5554 \ No newline at end of file diff --git a/README.md b/README.md index 6e537ce5..71f75af2 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,11 @@ These requirements are for the node/react components of this sample NFT project Use either `yarn install` or `npm install` to install all the required node packages. +With `hardhat` -> Run commands with `--verbose` at the end + +## Minting the NFTs +`npx hardhat run scripts/deploy.js --network rinkeby --verbose` + ## 🚀 Technologies Used diff --git a/contracts/GameContent.sol b/contracts/GameContent.sol index 9964f380..b9d835f3 100644 --- a/contracts/GameContent.sol +++ b/contracts/GameContent.sol @@ -14,14 +14,14 @@ import "./libraries/Base64.sol"; contract GameContent is ERC721 { // Character's attributes struct CharacterAttributes { - uint characterIndex; + uint256 characterIndex; string name; string imageURI; - uint hp; - uint maxHp; - uint attackDamage; + uint256 hp; + uint256 maxHp; + uint256 attackDamage; } - + // tokenId Counter function using Counters for Counters.Counter; Counters.Counter private _tokenIds; @@ -31,6 +31,17 @@ contract GameContent is ERC721 { // Mapping the nft's tokenId => character's attributes mapping(uint256 => CharacterAttributes) public nftHolderAttributes; + + // Boss struct + struct Boss { + string name; + string imageURI; + uint256 hp; + uint256 maxHp; + uint256 attackDamage; + } + Boss public bossCharacter; + // Mapping from an address => tokenId mapping(address => uint256) public nftHolders; @@ -38,32 +49,57 @@ contract GameContent is ERC721 { constructor( string[] memory characterNames, string[] memory characterImageURIs, - uint[] memory characterHP, - uint[] memory characterAttackDmg - ) - ERC721("Gears", "GEAR") - { + uint256[] memory characterHP, + uint256[] memory characterAttackDmg, + string memory bossName, // New variables are pased in run.js (and therefore deploy.js) + string memory bossImageURI, + uint256 bossHp, + uint256 bossAttackDamage + ) ERC721("Gears", "GEAR") { // Initialize default data for each character - for(uint i = 0; i < characterNames.length; i += 1) { - defaultCharacters.push(CharacterAttributes({ - characterIndex: i, - name: characterNames[i], - imageURI: characterImageURIs[i], - hp: characterHP[i], - maxHp: characterHP[i], - attackDamage: characterAttackDmg[i] - })); + for (uint256 i = 0; i < characterNames.length; i += 1) { + defaultCharacters.push( + CharacterAttributes({ + characterIndex: i, + name: characterNames[i], + imageURI: characterImageURIs[i], + hp: characterHP[i], + maxHp: characterHP[i], + attackDamage: characterAttackDmg[i] + }) + ); CharacterAttributes memory c = defaultCharacters[i]; - console.log("Done initializing %s w/ HP %s", c.name, c.hp, c.imageURI); + console.log( + "Done initializing %s w/ HP %s", + c.name, + c.hp, + c.imageURI + ); } + // Initialise the boss character + bossCharacter = Boss({ + name: bossName, + imageURI: bossImageURI, + hp: bossHp, + maxHp: bossHp, + attackDamage: bossAttackDamage + }); + + console.log( + "Done initialising boss %s with HP %s, img %s", + bossCharacter.name, + bossCharacter.hp, + bossCharacter.imageURI + ); + // Initialize the tokenId counter, starting at index 1 _tokenIds.increment(); } // Mint NFT based on characterId input - function mintCharacterNFT(uint _characterIndex) external { + function mintCharacterNFT(uint256 _characterIndex) external { uint256 newItemId = _tokenIds.current(); // Assigns the tokenId to the caller's wallet (address) @@ -79,7 +115,11 @@ contract GameContent is ERC721 { attackDamage: defaultCharacters[_characterIndex].attackDamage }); - console.log("Minted NFT w/ tokenId %s and characterIndex %s", newItemId, _characterIndex); + console.log( + "Minted NFT w/ tokenId %s and characterIndex %s", + newItemId, + _characterIndex + ); // See who owns different NFTs nftHolders[msg.sender] = newItemId; @@ -88,30 +128,44 @@ contract GameContent is ERC721 { _tokenIds.increment(); } -function tokenURI(uint256 _tokenId) public view override returns (string memory) { - CharacterAttributes memory charAttributes = nftHolderAttributes[_tokenId]; // Retrieves the specific NFT's ddata by querying using _tokenId (which was passed in the function) - - string memory strHp = Strings.toString(charAttributes.hp); - string memory strMaxHp = Strings.toString(charAttributes.maxHp); - string memory strAttackDamage = Strings.toString(charAttributes.attackDamage); - - string memory json = Base64.encode( - abi.encodePacked( - '{"name": "', - charAttributes.name, - ' -- NFT #: ', - Strings.toString(_tokenId), - '", "description": "This is an NFT that lets people play in the game Metaverse Slayer!", "image": "', - charAttributes.imageURI, - '", "attributes": [ { "trait_type": "Health Points", "value": ',strHp,', "max_value":',strMaxHp,'}, { "trait_type": "Attack Damage", "value": ', - strAttackDamage,'} ]}' - ) - ); - - string memory output = string( - abi.encodePacked("data:application/json;base64,", json) - ); - - return output; + function tokenURI(uint256 _tokenId) + public + view + override + returns (string memory) + { + CharacterAttributes memory charAttributes = nftHolderAttributes[ + _tokenId + ]; // Retrieves the specific NFT's ddata by querying using _tokenId (which was passed in the function) + + string memory strHp = Strings.toString(charAttributes.hp); + string memory strMaxHp = Strings.toString(charAttributes.maxHp); + string memory strAttackDamage = Strings.toString( + charAttributes.attackDamage + ); + + string memory json = Base64.encode( + abi.encodePacked( + '{"name": "', + charAttributes.name, + " -- NFT #: ", + Strings.toString(_tokenId), + '", "description": "This is an NFT that lets people play in the game Metaverse Slayer!", "image": "', + charAttributes.imageURI, + '", "attributes": [ { "trait_type": "Health Points", "value": ', + strHp, + ', "max_value":', + strMaxHp, + '}, { "trait_type": "Attack Damage", "value": ', + strAttackDamage, + "} ]}" + ) + ); + + string memory output = string( + abi.encodePacked("data:application/json;base64,", json) + ); + + return output; } -} \ No newline at end of file +} diff --git a/hardhat.config.js b/hardhat.config.js index 9d8770df..dd47e499 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -17,11 +17,11 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { * @type import('hardhat/config').HardhatUserConfig */ module.exports = { - solidity: '0.8.0', + solidity: '0.8.1', networks: { rinkeby: { - url: 'YOUR ALCHEMY_API_URL', - accounts: ['YOUR_PRIVATE_RINKEBY_ACCOUNT_KEY'], + url: 'env.alchemy', + accounts: ['env.rinkeby'], }, }, -}; \ No newline at end of file +}; diff --git a/scripts/deploy.js b/scripts/deploy.js index 2a33aad9..288dce1a 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -8,7 +8,11 @@ const main = async () => { "https://i.imgur.com/xVu4vFL.png", "https://i.imgur.com/WMB6g9u.png"], [100, 200, 300], // HP Values - [100, 50, 25] // Attack damage values + [100, 50, 25], // Attack damage values + "Scroobus", // Boss name + "https://i.imgur.com/AksR0tt.png", // Boss image + 10000, // Boss HP + 500 // Boss attack damage ); // Hardhat creates a local Eth network just for this contract with refresh for every deploy await gameContract.deployed(); // Wait until the contract is mined & deployed to the (current) local blockchain console.log("Contract deployed to:", gameContract.address); diff --git a/scripts/run.js b/scripts/run.js index 66bc2cca..557d9467 100644 --- a/scripts/run.js +++ b/scripts/run.js @@ -8,7 +8,11 @@ const main = async () => { "https://i.imgur.com/xVu4vFL.png", "https://i.imgur.com/WMB6g9u.png"], [100, 200, 300], // HP Values - [100, 50, 25] // Attack damage values + [100, 50, 25], // Attack damage values + "Scroobus", // Boss name + "https://i.imgur.com/AksR0tt.png", // Boss image + 10000, // Boss HP + 500 // Boss attack damage ); // Hardhat creates a local Eth network just for this contract with refresh for every deploy await gameContract.deployed(); // Wait until the contract is mined & deployed to the (current) local blockchain console.log("Contract deployed to:", gameContract.address);