- Remove executable permissions from configuration files (.editorconfig, .env.example, .gitignore) - Remove executable permissions from documentation files (README.md, LICENSE, SECURITY.md) - Remove executable permissions from web assets (HTML, CSS, JS files) - Remove executable permissions from data files (JSON, SQL, YAML, requirements.txt) - Remove executable permissions from source code files across all apps - Add executable permissions to Python
121 lines
4.3 KiB
Solidity
121 lines
4.3 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
|
|
contract KnowledgeGraphMarket is Ownable, ReentrancyGuard {
|
|
using SafeERC20 for IERC20;
|
|
|
|
IERC20 public aitbcToken;
|
|
uint256 public graphCounter;
|
|
uint256 public platformFeePercentage = 250; // 2.5%
|
|
|
|
struct KnowledgeGraph {
|
|
uint256 id;
|
|
address creator;
|
|
string cid;
|
|
string metadataURI; // Added to match broader plan
|
|
uint256 price;
|
|
uint256 totalSales;
|
|
bool isActive;
|
|
}
|
|
|
|
struct Purchase {
|
|
uint256 graphId;
|
|
address buyer;
|
|
uint256 timestamp;
|
|
string encryptedKey; // The decryption key encrypted with the buyer's public key
|
|
}
|
|
|
|
mapping(uint256 => KnowledgeGraph) public graphs;
|
|
mapping(uint256 => mapping(address => bool)) public hasPurchased;
|
|
|
|
// graphId => array of purchases
|
|
mapping(uint256 => Purchase[]) public purchases;
|
|
|
|
event GraphListed(uint256 indexed id, address indexed creator, string cid, string metadataURI, uint256 price);
|
|
event GraphUpdated(uint256 indexed id, uint256 newPrice, bool isActive);
|
|
event GraphPurchased(uint256 indexed id, address indexed buyer, uint256 price);
|
|
event KeyDelivered(uint256 indexed id, address indexed buyer, string encryptedKey);
|
|
|
|
constructor(address _aitbcToken) {
|
|
aitbcToken = IERC20(_aitbcToken);
|
|
}
|
|
|
|
function listGraph(string calldata _cid, string calldata _metadataURI, uint256 _price) external returns (uint256) {
|
|
uint256 id = graphCounter++;
|
|
graphs[id] = KnowledgeGraph(id, msg.sender, _cid, _metadataURI, _price, 0, true);
|
|
emit GraphListed(id, msg.sender, _cid, _metadataURI, _price);
|
|
return id;
|
|
}
|
|
|
|
function updateGraph(uint256 _id, uint256 _newPrice, bool _isActive) external {
|
|
KnowledgeGraph storage graph = graphs[_id];
|
|
require(graph.creator == msg.sender, "Not creator");
|
|
|
|
graph.price = _newPrice;
|
|
graph.isActive = _isActive;
|
|
|
|
emit GraphUpdated(_id, _newPrice, _isActive);
|
|
}
|
|
|
|
function purchaseGraph(uint256 _id) external nonReentrant {
|
|
KnowledgeGraph storage graph = graphs[_id];
|
|
require(graph.isActive, "Graph inactive");
|
|
require(!hasPurchased[_id][msg.sender], "Already purchased");
|
|
require(graph.creator != msg.sender, "Cannot buy own graph");
|
|
|
|
uint256 fee = (graph.price * platformFeePercentage) / 10000;
|
|
uint256 creatorAmount = graph.price - fee;
|
|
|
|
aitbcToken.safeTransferFrom(msg.sender, address(this), fee); // Treasury
|
|
aitbcToken.safeTransferFrom(msg.sender, graph.creator, creatorAmount);
|
|
|
|
graph.totalSales++;
|
|
hasPurchased[_id][msg.sender] = true;
|
|
|
|
purchases[_id].push(Purchase({
|
|
graphId: _id,
|
|
buyer: msg.sender,
|
|
timestamp: block.timestamp,
|
|
encryptedKey: ""
|
|
}));
|
|
|
|
emit GraphPurchased(_id, msg.sender, graph.price);
|
|
}
|
|
|
|
function deliverDecryptionKey(uint256 _id, address _buyer, string calldata _encryptedKey) external {
|
|
KnowledgeGraph storage graph = graphs[_id];
|
|
require(graph.creator == msg.sender, "Not creator");
|
|
require(hasPurchased[_id][_buyer], "Buyer has not purchased");
|
|
|
|
Purchase[] storage graphPurchases = purchases[_id];
|
|
bool found = false;
|
|
for (uint i = 0; i < graphPurchases.length; i++) {
|
|
if (graphPurchases[i].buyer == _buyer) {
|
|
graphPurchases[i].encryptedKey = _encryptedKey;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
require(found, "Purchase record not found");
|
|
|
|
emit KeyDelivered(_id, _buyer, _encryptedKey);
|
|
}
|
|
|
|
function getMyPurchaseKey(uint256 _id) external view returns (string memory) {
|
|
require(hasPurchased[_id][msg.sender], "Not purchased");
|
|
|
|
Purchase[] storage graphPurchases = purchases[_id];
|
|
for (uint i = 0; i < graphPurchases.length; i++) {
|
|
if (graphPurchases[i].buyer == msg.sender) {
|
|
return graphPurchases[i].encryptedKey;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
}
|