Decentralized Wholesale Platform
What it does:
Facilitates direct wholesale transactions between suppliers and buyers on-chain, automating listings, negotiations, and payments.
Why it matters:
Eliminates intermediaries, reduces fees, enforces transparent contracts, and provides auditable records of transactions for all parties.
How it works:
-
Suppliers list products with quantity, pricing, and terms on-chain
-
Buyers can browse, place orders, and commit payments via smart contracts
-
Milestone-based or Just-In-Time payments can be triggered automatically upon delivery
-
Ratings and reviews feed into supplier reputation scoring
-
Integrates with Supplier Reputation System, Cross-Border Trade Settlement, and Product Lifecycle Tracking
-
Dashboards provide real-time visibility into available products, orders, and settlement status
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title DecentralizedWholesale
* @author Nam
* @notice Enables on-chain wholesale listings, orders, and payments
*/
contract DecentralizedWholesale is Ownable {
struct Product {
string name;
uint256 pricePerUnit;
uint256 quantityAvailable;
address payable supplier;
bool active;
}
struct Order {
uint256 productId;
uint256 quantity;
address payable buyer;
uint256 totalAmount;
bool fulfilled;
}
mapping(uint256 => Product) public products;
mapping(uint256 => Order) public orders;
uint256 public productCount;
uint256 public orderCount;
mapping(address => bool) public authorizedSuppliers;
// -------------------- EVENTS --------------------
event SupplierApproved(address supplier);
event ProductListed(uint256 productId, string name, uint256 pricePerUnit, uint256 quantity, address supplier);
event OrderPlaced(uint256 orderId, uint256 productId, address buyer, uint256 quantity, uint256 totalAmount);
event OrderFulfilled(uint256 orderId);
// -------------------- SUPPLIER MANAGEMENT --------------------
function approveSupplier(address _supplier) external onlyOwner {
authorizedSuppliers[_supplier] = true;
emit SupplierApproved(_supplier);
}
function revokeSupplier(address _supplier) external onlyOwner {
authorizedSuppliers[_supplier] = false;
}
modifier onlySupplier() {
require(authorizedSuppliers[msg.sender], "Not an authorized supplier");
_;
}
// -------------------- PRODUCT MANAGEMENT --------------------
function listProduct(string calldata _name, uint256 _pricePerUnit, uint256 _quantity) external onlySupplier {
require(_quantity > 0, "Quantity must be > 0");
require(_pricePerUnit > 0, "Price must be > 0");
productCount += 1;
products[productCount] = Product({
name: _name,
pricePerUnit: _pricePerUnit,
quantityAvailable: _quantity,
supplier: payable(msg.sender),
active: true
});
emit ProductListed(productCount, _name, _pricePerUnit, _quantity, msg.sender);
}
// -------------------- ORDER MANAGEMENT --------------------
function placeOrder(uint256 _productId, uint256 _quantity) external payable {
Product storage p = products[_productId];
require(p.active, "Product not active");
require(_quantity > 0 && _quantity <= p.quantityAvailable, "Invalid quantity");
uint256 total = _quantity * p.pricePerUnit;
require(msg.value == total, "Incorrect payment amount");
orderCount += 1;
orders[orderCount] = Order({
productId: _productId,
quantity: _quantity,
buyer: payable(msg.sender),
totalAmount: total,
fulfilled: false
});
p.quantityAvailable -= _quantity;
emit OrderPlaced(orderCount, _productId, msg.sender, _quantity, total);
}
function fulfillOrder(uint256 _orderId) external onlySupplier {
Order storage o = orders[_orderId];
Product storage p = products[o.productId];
require(msg.sender == p.supplier, "Not the supplier");
require(!o.fulfilled, "Order already fulfilled");
o.fulfilled = true;
p.supplier.transfer(o.totalAmount);
emit OrderFulfilled(_orderId);
}
// -------------------- VIEW FUNCTIONS --------------------
function getProduct(uint256 _productId) external view returns (Product memory) {
return products[_productId];
}
function getOrder(uint256 _orderId) external view returns (Order memory) {
return orders[_orderId];
}
}