// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract PurchaseContract {
address public owner;
uint256 public feePercentage = 2;
struct Purchase {
bytes32 ethsId;
bytes32 listId;
address listAddress;
uint256 price;
bool isPurchased;
}
mapping(bytes32 => Purchase) public purchases;
event PurchaseMade(address from, address to, bytes32 listHash);
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function.");
_;
}
function setFeePercentage(uint256 newFee) public onlyOwner {
feePercentage = newFee;
}
function buy(bytes32 ethsId, bytes32 listId, address listAddress, uint256 price) public payable {
bytes32 purchaseHash = keccak256(abi.encodePacked(ethsId, listId));
require(!purchases[purchaseHash].isPurchased, "This item is already purchased.");
require(msg.value == price, "Incorrect price.");
purchases[purchaseHash] = Purchase(ethsId, listId, listAddress, price, true);
uint256 fee = (price * feePercentage) / 100;
uint256 amountToSend = price - fee;
payable(listAddress).transfer(amountToSend);
// The fee remains in the contract
emit PurchaseMade(msg.sender, listAddress, purchaseHash);
}
function withdraw(uint256 amount) public onlyOwner {
uint256 balance = address(this).balance;
require(amount > 0, "Amount must be greater than 0");
require(balance >= amount, "Insufficient funds in contract");
payable(owner).transfer(amount);
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "New owner cannot be the zero address");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
{
"compilationTarget": {
"PurchaseContract.sol": "PurchaseContract"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes32","name":"listHash","type":"bytes32"}],"name":"PurchaseMade","type":"event"},{"inputs":[{"internalType":"bytes32","name":"ethsId","type":"bytes32"},{"internalType":"bytes32","name":"listId","type":"bytes32"},{"internalType":"address","name":"listAddress","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"feePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"purchases","outputs":[{"internalType":"bytes32","name":"ethsId","type":"bytes32"},{"internalType":"bytes32","name":"listId","type":"bytes32"},{"internalType":"address","name":"listAddress","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"isPurchased","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"setFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]