
Building a Decentralized Marketplace in Solidity
Overview of the Marketplace Smart Contract
The decentralized marketplace will consist of the following functionalities:
- Listing an Item: Users can create listings for items they wish to sell.
- Purchasing an Item: Other users can purchase listed items.
- Retrieving Listings: Users can view all active listings.
- Managing Ownership: Ensure that only the item owner can modify or remove their listings.
Smart Contract Code
Below is the complete code for the decentralized marketplace smart contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract DecentralizedMarketplace {
struct Item {
uint id;
string name;
uint price;
address payable seller;
bool isSold;
}
mapping(uint => Item) public items;
mapping(address => uint[]) public userItems;
uint public itemCount;
event ItemListed(uint id, string name, uint price, address seller);
event ItemPurchased(uint id, address buyer);
function listItem(string memory _name, uint _price) public {
require(_price > 0, "Price must be greater than zero");
itemCount++;
items[itemCount] = Item(itemCount, _name, _price, payable(msg.sender), false);
userItems[msg.sender].push(itemCount);
emit ItemListed(itemCount, _name, _price, msg.sender);
}
function purchaseItem(uint _id) public payable {
Item storage item = items[_id];
require(_id > 0 && _id <= itemCount, "Item does not exist");
require(msg.value == item.price, "Incorrect price sent");
require(!item.isSold, "Item already sold");
require(item.seller != msg.sender, "Seller cannot purchase their own item");
item.seller.transfer(msg.value);
item.isSold = true;
emit ItemPurchased(_id, msg.sender);
}
function getItem(uint _id) public view returns (Item memory) {
require(_id > 0 && _id <= itemCount, "Item does not exist");
return items[_id];
}
function getUserItems(address _user) public view returns (uint[] memory) {
return userItems[_user];
}
}Explanation of the Code
- Struct Definition: The
Itemstruct defines the properties of an item, including its ID, name, price, seller's address, and sold status.
- Mappings:
items: Maps item IDs to their correspondingItemstructs.userItems: Maps user addresses to an array of item IDs they have listed.
- Events:
ItemListed: Emitted when a new item is listed.ItemPurchased: Emitted when an item is purchased.
- Functions:
listItem: Allows users to list an item with a name and price. It checks that the price is greater than zero and updates the state accordingly.purchaseItem: Allows users to purchase an item. It verifies that the item exists, the correct price is sent, and the item is not already sold.getItem: Returns the details of a specific item.getUserItems: Returns an array of item IDs listed by a specific user.
Best Practices in Smart Contract Development
When developing smart contracts, it is essential to adhere to best practices to ensure security and efficiency:
| Best Practice | Description |
|---|---|
Use require for Validation | Always validate inputs and state changes using require to prevent invalid transactions. |
| Emit Events | Emit events for significant state changes to enable easy tracking of contract activity. |
| Avoid Reentrancy Attacks | Use the Checks-Effects-Interactions pattern to avoid reentrancy vulnerabilities. |
| Limit Gas Consumption | Optimize your code to minimize gas costs, especially in loops and storage operations. |
| Use Modifiers for Access Control | Implement modifiers to manage access control and reduce code duplication. |
Conclusion
In this tutorial, we have built a decentralized marketplace using Solidity. This contract allows users to list items for sale and purchase them securely. By following best practices, we can ensure that our smart contracts are robust and maintainable.
