The purpose of this library is to facilitate the creation, management and trading of digital assets in blockchain gaming. This library ensures secure, decentralized asset ownership and trading, enabling players to fully control their assets and engage in economic activities within the game ecosystem.
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"@openzeppelin/contracts/token/ERC721/ERC721.sol";import"@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";import"@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";import"@openzeppelin/contracts/access/Ownable.sol";import"@openzeppelin/contracts/utils/Counters.sol";contractEvireAssetTradingLibraryisERC721, ERC721Enumerable, ERC721URIStorage, Ownable {usingCountersforCounters.Counter; Counters.Counter private _tokenIdCounter;structAsset {uint256 id;string name;string metadataURI;uint256 price;bool forSale; }mapping(uint256=> Asset) private assets;eventAssetCreated(uint256indexed assetId, string name, string metadataURI, uint256 price);eventAssetForSale(uint256indexed assetId, uint256 price);eventAssetSold(uint256indexed assetId, addressindexed buyer, uint256 price);eventAssetRemovedFromSale(uint256indexed assetId);constructor() ERC721("EvireAsset", "EVA") {}functioncreateAsset(stringmemory name,stringmemory metadataURI,uint256 price) publiconlyOwner {uint256 assetId = _tokenIdCounter.current(); _tokenIdCounter.increment(); assets[assetId] =Asset(assetId, name, metadataURI, price,false);_mint(msg.sender, assetId);_setTokenURI(assetId, metadataURI);emitAssetCreated(assetId, name, metadataURI, price); }functionlistAssetForSale(uint256 assetId,uint256 price) publiconlyOwner {require(_exists(assetId),"Asset does not exist");require(ownerOf(assetId) == msg.sender,"You do not own this asset"); assets[assetId].price = price; assets[assetId].forSale =true;emitAssetForSale(assetId, price); }functionbuyAsset(uint256 assetId) publicpayable {require(_exists(assetId),"Asset does not exist");require(assets[assetId].forSale,"Asset is not for sale");require(msg.value == assets[assetId].price,"Incorrect price");address owner =ownerOf(assetId);_transfer(owner, msg.sender, assetId);payable(owner).transfer(msg.value); assets[assetId].forSale =false;emitAssetSold(assetId, msg.sender, msg.value); }functionremoveAssetFromSale(uint256 assetId) publiconlyOwner {require(_exists(assetId),"Asset does not exist");require(assets[assetId].forSale,"Asset is not for sale"); assets[assetId].forSale =false;emitAssetRemovedFromSale(assetId); } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId); }function_burn(uint256 tokenId) internaloverride(ERC721,ERC721URIStorage) { super._burn(tokenId); }functiontokenURI(uint256 tokenId) publicviewoverride(ERC721,ERC721URIStorage) returns (stringmemory) {return super.tokenURI(tokenId); }functionsupportsInterface(bytes4 interfaceId) publicviewoverride(ERC721,ERC721Enumerable) returns (bool) {return super.supportsInterface(interfaceId); }}
Example Usage
This dApp will manage a marketplace for unique digital assets where users can create, list for sale, buy and remove assets from sale.
Smart Contract
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"./GaminFW/EvireAssetTradingLibrary.sol";contract EvireMarketplace { EvireAssetTradingLibrary private assetLibrary;eventNewAsset(uint256indexed assetId, string name, string metadataURI, uint256 price);eventAssetListedForSale(uint256indexed assetId, uint256 price);eventAssetPurchased(uint256indexed assetId, addressindexed buyer, uint256 price);eventAssetDelisted(uint256indexed assetId);constructor(address_assetLibraryAddress) { assetLibrary =EvireAssetTradingLibrary(_assetLibraryAddress); }functioncreateAsset(stringmemory name,stringmemory metadataURI,uint256 price) public { assetLibrary.createAsset(name, metadataURI, price);uint256 assetId = assetLibrary.totalSupply() -1; // Assuming the new asset ID is the last one createdemitNewAsset(assetId, name, metadataURI, price); }functionlistAssetForSale(uint256 assetId,uint256 price) public { assetLibrary.listAssetForSale(assetId, price);emitAssetListedForSale(assetId, price); }functionbuyAsset(uint256 assetId) publicpayable { uint256 price = assetLibrary.assets(assetId).price; // Assuming a getter function exists in EvireAssetTradingLibrary
require(msg.value == price,"Incorrect value sent"); assetLibrary.buyAsset{value: msg.value}(assetId);emitAssetPurchased(assetId, msg.sender, price); }functionremoveAssetFromSale(uint256 assetId) public { assetLibrary.removeAssetFromSale(assetId);emitAssetDelisted(assetId); }functiongetAssetDetails(uint256 assetId) publicviewreturns (EvireAssetTradingLibrary.Assetmemory) {return assetLibrary.assets(assetId); // Assuming a getter function exists in EvireAssetTradingLibrary }functiontotalAssets() publicviewreturns (uint256) {return assetLibrary.totalSupply(); }}
Web3.js Integration
Below is a JavaScript example using Web3.js to interact with the deployed EvireMarketplace smart contract. This will include functions to create an asset, list it for sale, buy it and remove it from sale.
constWeb3=require('web3');constweb3=newWeb3('http://localhost:8545'); // Change to your Ethereum node URLconstmarketplaceAbi= [...] // ABI of the EvireMarketplace contractconstmarketplaceAddress='0x...'; // Deployed address of the EvireMarketplace contractconstmarketplace=newweb3.eth.Contract(marketplaceAbi, marketplaceAddress);// Example account addressesconstowner='0x...'; // The owner addressconstbuyer='0x...'; // The buyer address// Create a new assetasyncfunctioncreateAsset(name, metadataURI, price) {constpriceInWei=web3.utils.toWei(price,'ether');awaitmarketplace.methods.createAsset(name, metadataURI, priceInWei).send({ from: owner });console.log(`Asset created: ${name}`);}// List an asset for saleasyncfunctionlistAssetForSale(assetId, price) {constpriceInWei=web3.utils.toWei(price,'ether');awaitmarketplace.methods.listAssetForSale(assetId, priceInWei).send({ from: owner });console.log(`Asset ${assetId} listed for sale at ${price} ETH`);}// Buy an assetasyncfunctionbuyAsset(assetId) {constassetDetails=awaitmarketplace.methods.getAssetDetails(assetId).call();constprice=assetDetails.price;awaitmarketplace.methods.buyAsset(assetId).send({ from: buyer, value: price });console.log(`Asset ${assetId} bought for ${web3.utils.fromWei(price,'ether')} ETH`);}// Remove an asset from saleasyncfunctionremoveAssetFromSale(assetId) {awaitmarketplace.methods.removeAssetFromSale(assetId).send({ from: owner });console.log(`Asset ${assetId} removed from sale`);}// Get asset detailsasyncfunctiongetAssetDetails(assetId) {constasset=awaitmarketplace.methods.getAssetDetails(assetId).call();console.log(`Asset ${assetId}:`, asset);}// Example usage(async () => {awaitcreateAsset('Asset Name','https://example.com/metadata.json','0.1');awaitlistAssetForSale(0,'0.1');awaitbuyAsset(0);awaitremoveAssetFromSale(0);awaitgetAssetDetails(0);})();
Explanation
Smart Contract:
The EvireMarketplace contract initializes with the address of the deployed EvireAssetTradingLibrary.
It exposes functions to create assets, list them for sale, buy them, and remove them from sale, while emitting corresponding events.
It provides a way to get asset details and the total number of assets.
Web3.js Integration:
This script uses Web3.js to interact with the smart contract.
It includes functions to create assets, list them for sale, buy them, and remove them from sale.
It demonstrates the usage of these functions in an example asynchronous function.