WEB3DSHOP for 3D NFTs
Date:
My Roles:
During the one-week Creative Media Summer workshop, we immersed ourselves in the world of blockchain and smart contracts. Day one introduced us to the fundamentals, day two saw us programming our own blockchain, and by the third day, we delved into smart contracts. Armed with this knowledge, we spent the next 1.5 days developing our own project - Web3DStore, a unique platform for trading 3D model NFTs. The results of this intense period of innovation and teamwork, which we'll delve into more technically later, are now ready for you to explore.
Let the show begin:
Idea
Imagine being a game developer in the pursuit of distinct 3D models for your game. Upon purchasing them from any 3D Asset Store, you run the risk of finding that the model has already been used in another game, recognized by the players, thus compromising its uniqueness. Furthermore, if your project direction changes, you are left holding a license for an asset you no longer require.
This is why we conceived Web3DShop. The primary benefit of this platform is that it ensures unambiguous ownership of a 3D model and its associated license via blockchain notation. It employs smart contracts to manage NFTs. Should you no longer require the 3D model, you have the option to resell the license. The ingenious part is that the original designer continues to benefit, receiving a portion of the resale price.
Homepage of Web3DShopTechnical Implementation
We used several frameworks to implement our project:
- Ethereum Goerli Test Chain: This is a testnet for the Ethereum blockchain, allowing us to test our decentralized application (dApp) in a sandboxed environment.
- Solidity: It's a statically typed, contract-oriented programming language for implementing smart contracts on Ethereum. We used Solidity to write the logic of our smart contracts, which handle the creation and trading of 3D model NFTs on our platform.
- Meta Mask: This is a cryptocurrency wallet which can interact with the Ethereum blockchain. We used MetaMask to facilitate user transactions on our platform, such as buying and selling NFTs.
- Inter Planetary File System: IPFS is a protocol and network designed to store and share data in a distributed file system. We used IPFS to store the 3D models and their metadata, ensuring that data remains accessible and resilient.
- Remix IDE: Remix is an open-source, web-based IDE for Solidity that simplifies the process of writing, testing, and deploying smart contracts. We used Remix IDE to streamline our Solidity coding and testing process.
- web3.js: This is a collection of libraries that enable interaction with a local or remote Ethereum node, using HTTP. We used web3.js to connect our dApp with Ethereum blockchain, facilitating the communication between the smart contracts and our website.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract MyNFT is ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
mapping(uint256 => Item) public items;
uint256[] public itemIDs; // New array to store item IDs
string[] public itemNames;
string[] public itemDescriptions;
string[] public itemCDIs;
mapping(address => uint256) public authorEarnings;
struct Item {
uint256 id;
string name;
string description;
uint256 price;
address author;
address payable seller;
string cdi;
bool isAvailable;
}
constructor() ERC721("MyNFT", "MNFT") {
}
function createItem(string memory name, string memory description, uint256 price, string memory cdi) public returns (uint256) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
Item memory newItem = Item({
id: newItemId,
name: name,
description: description,
price: price,
author: msg.sender,
seller: payable(msg.sender),
cdi: cdi,
isAvailable: true
});
items[newItemId] = newItem;
itemIDs.push(newItemId); // Store new item ID
itemNames.push(name);
itemDescriptions.push(description);
itemCDIs.push(cdi);
return newItemId;
}
function buyItem(uint256 itemId) public payable {
Item storage item = items[itemId];
require(item.isAvailable, "Item not available");
require(msg.value >= item.price, "Price not met");
// Transfer the NFT from the seller to the buyer
_transfer(item.seller, msg.sender, itemId);
// Pay the seller and the author
uint256 authorPayment = (item.price * 20) / 100;
uint256 sellerPayment = item.price - authorPayment;
item.seller.transfer(sellerPayment);
authorEarnings[item.author] += authorPayment;
// Update the seller field for the item
items[itemId].seller = payable(msg.sender);
items[itemId].isAvailable = false;
}
function makeAvailable(uint256 itemId, uint256 newPrice) public {
Item storage item = items[itemId];
require(msg.sender == item.seller, "Only the owner can make the item available");
item.isAvailable = true;
item.price = newPrice;
}
function getAllItems() public view returns (uint256[] memory, string[] memory, string[] memory, string[] memory) {
return (itemIDs, itemNames, itemDescriptions, itemCDIs);
}
function getItemDetails(uint256 itemId) public view returns (uint256, string memory, string memory, uint256, address, address, string memory, bool) {
Item storage item = items[itemId];
return (item.id, item.name, item.description, item.price, item.author, item.seller, item.cdi, item.isAvailable);
}
}
Smart Contract coded with Solidity