feat: finish phase 2 decentralized memory and storage tasks
This commit is contained in:
@@ -3,10 +3,16 @@ pragma solidity ^0.8.19;
|
||||
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
||||
import "./ZKReceiptVerifier.sol";
|
||||
|
||||
contract AgentMemory is Ownable, ReentrancyGuard {
|
||||
ZKReceiptVerifier public zkVerifier;
|
||||
|
||||
struct MemoryAnchor {
|
||||
string cid;
|
||||
string memoryType; // e.g., "vector_db", "knowledge_graph"
|
||||
bytes32 zkProofHash;
|
||||
bool isEncrypted;
|
||||
uint256 timestamp;
|
||||
uint256 version;
|
||||
}
|
||||
@@ -14,26 +20,74 @@ contract AgentMemory is Ownable, ReentrancyGuard {
|
||||
mapping(address => MemoryAnchor[]) public agentMemories;
|
||||
mapping(address => uint256) public agentMemoryVersions;
|
||||
|
||||
event MemoryAnchored(address indexed agent, string cid, uint256 version, uint256 timestamp);
|
||||
event MemoryAnchored(
|
||||
address indexed agent,
|
||||
string cid,
|
||||
string memoryType,
|
||||
bytes32 zkProofHash,
|
||||
bool isEncrypted,
|
||||
uint256 version,
|
||||
uint256 timestamp
|
||||
);
|
||||
|
||||
function anchorMemory(string calldata _cid) external nonReentrant {
|
||||
constructor(address _zkVerifierAddress) {
|
||||
if (_zkVerifierAddress != address(0)) {
|
||||
zkVerifier = ZKReceiptVerifier(_zkVerifierAddress);
|
||||
}
|
||||
}
|
||||
|
||||
function updateZKVerifier(address _newVerifier) external onlyOwner {
|
||||
require(_newVerifier != address(0), "Invalid address");
|
||||
zkVerifier = ZKReceiptVerifier(_newVerifier);
|
||||
}
|
||||
|
||||
function anchorMemory(
|
||||
string calldata _cid,
|
||||
string calldata _memoryType,
|
||||
bytes32 _zkProofHash,
|
||||
bytes calldata _proof,
|
||||
bool _isEncrypted
|
||||
) external nonReentrant {
|
||||
require(bytes(_cid).length > 0, "Invalid CID");
|
||||
require(bytes(_memoryType).length > 0, "Invalid memory type");
|
||||
|
||||
// Verify ZK Proof if provided and verifier is set
|
||||
if (_zkProofHash != bytes32(0) && address(zkVerifier) != address(0)) {
|
||||
require(_proof.length > 0, "Proof required for hash");
|
||||
bool isValid = zkVerifier.verifyReceipt(_proof, _zkProofHash);
|
||||
require(isValid, "ZK Proof verification failed");
|
||||
}
|
||||
|
||||
uint256 nextVersion = agentMemoryVersions[msg.sender] + 1;
|
||||
|
||||
agentMemories[msg.sender].push(MemoryAnchor({
|
||||
cid: _cid,
|
||||
memoryType: _memoryType,
|
||||
zkProofHash: _zkProofHash,
|
||||
isEncrypted: _isEncrypted,
|
||||
timestamp: block.timestamp,
|
||||
version: nextVersion
|
||||
}));
|
||||
|
||||
agentMemoryVersions[msg.sender] = nextVersion;
|
||||
|
||||
emit MemoryAnchored(msg.sender, _cid, nextVersion, block.timestamp);
|
||||
emit MemoryAnchored(
|
||||
msg.sender,
|
||||
_cid,
|
||||
_memoryType,
|
||||
_zkProofHash,
|
||||
_isEncrypted,
|
||||
nextVersion,
|
||||
block.timestamp
|
||||
);
|
||||
}
|
||||
|
||||
function getLatestMemory(address _agent) external view returns (MemoryAnchor memory) {
|
||||
require(agentMemories[_agent].length > 0, "No memory anchored");
|
||||
return agentMemories[_agent][agentMemories[_agent].length - 1];
|
||||
}
|
||||
|
||||
function getMemoryCount(address _agent) external view returns (uint256) {
|
||||
return agentMemories[_agent].length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,42 +17,104 @@ contract KnowledgeGraphMarket is Ownable, ReentrancyGuard {
|
||||
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, uint256 price);
|
||||
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, uint256 _price) external returns (uint256) {
|
||||
function listGraph(string calldata _cid, string calldata _metadataURI, uint256 _price) external returns (uint256) {
|
||||
uint256 id = graphCounter++;
|
||||
graphs[id] = KnowledgeGraph(id, msg.sender, _cid, _price, 0, true);
|
||||
emit GraphListed(id, msg.sender, _cid, _price);
|
||||
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), graph.price);
|
||||
aitbcToken.safeTransfer(graph.creator, creatorAmount);
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user