Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: Auto-EVM-Store #106

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "packages/auto-key-store/lib/forge-std"]
path = packages/auto-key-store/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "packages/auto-key-store/lib/openzeppelin-contracts"]
path = packages/auto-key-store/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
4 changes: 4 additions & 0 deletions .vscode/auto.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
"name": "Auto-XDM",
"path": "../packages/auto-xdm",
},
{
"name": "Auto-EVM-Storage",
"path": "../packages/auto-evm-storage",
},
{
"name": "Example - NextJS",
"path": "../examples/next",
Expand Down
2 changes: 2 additions & 0 deletions packages/auto-evm-storage/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out/
cache/
62 changes: 62 additions & 0 deletions packages/auto-evm-storage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# @autonomys/auto-emv-storage

A comprehensive npm package for deploying and interacting with various data structure smart contracts on Autonomys Nova (EVM) domains. This package provides a simple and efficient way to manage different types of data structures on the blockchain.

## Features

- Easy deployment and interaction with multiple smart contract data structures:

- AutoKeyValue: Key-value store with role-based access control
- AutoEnumerableMap: Enumerable map with key-value pairs
- AutoMultiMap: Multi-map allowing multiple values per key
- AutoLinkedList: Linked list implementation
- AutoStackQueue: Combined stack and queue data structure
- AutoEventLogger: Event logging and retrieval system

- Simple TypeScript API for interacting with each data structure
- Role-based access control for writers and editors (where applicable)
- Seamless integration with Ethereum-compatible networks

## Installation

To install the package, use npm or yarn:

```bash
npm install @autonomys/auto-evm-storage
# or
yarn add @autonomys/auto-evm-storage
```

## Usage

### AutoKeyValue

The `AutoKeyValue` contract is a key-value store with role-based access control. It allows for setting and retrieving values associated with specific keys.

#### Deployment

To deploy the `AutoKeyValue` contract, use the following TypeScript code:

```typescript
import { AutoKeyValue } from '@autonomys/auto-evm-storage'

const autoKeyValue = new AutoKeyValue(provider)
```

#### Setting and Retrieving Values

To set a value for a key, use the `setValue` method:

```typescript
const value = await autoKeyValue.setValue('key', 'value')
```

To retrieve a value for a key, use the `getValue` method:

```typescript
const value = await autoKeyValue.getValue('key')
```

### AutoEnumerableMap

The `AutoEnumerableMap` contract is an enumerable map with key-value pairs. It allows for setting and retrieving values associated with specific keys.
3 changes: 3 additions & 0 deletions packages/auto-evm-storage/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[profile.default]
solc_version = "0.8.19"
rpc_url = "https://nova.autonomy.network"
31 changes: 31 additions & 0 deletions packages/auto-evm-storage/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@autonomys/auto-emv-storage",
"version": "0.1.0",
"main": "dist/index.js",
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"test": "forge test"
},
"dependencies": {
"ethers": "^5.4.0"
},
"repository": {
"type": "git",
"url": "https://github.com/autonomys/auto-sdk"
},
"author": {
"name": "Autonomys",
"url": "https://www.autonomys.net"
},
"devDependencies": {
"@types/node": "^14.0.0",
"tsup": "^5.0.0",
"typescript": "^4.0.0"
},
"description": "A compact npm package for deploying and interacting with different types of storage smart contracts on Autonomy's Nova network.",
"directories": {
"test": "test"
},
"keywords": [],
"license": "MIT"
}
5 changes: 5 additions & 0 deletions packages/auto-evm-storage/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=lib/forge-std/src/
@openzeppelin-contracts/=lib/openzeppelin-contracts/
@openzeppelin/=lib/openzeppelin-contracts/
20 changes: 20 additions & 0 deletions packages/auto-evm-storage/script/DeployAutoEnumerableMap.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/AutoEnumerableMap.sol";

contract DeployAutoEnumerableMap is Script {
function run() external {
vm.startBroadcast();

AutoEnumerableMap autoEnumerableMap = new AutoEnumerableMap(msg.sender);

// Example usage
bytes32 key = keccak256(abi.encodePacked("exampleKey"));
bytes32 value = keccak256(abi.encodePacked("exampleValue"));
autoEnumerableMap.set(key, value);

vm.stopBroadcast();
}
}
18 changes: 18 additions & 0 deletions packages/auto-evm-storage/script/DeployAutoEventLogger.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/AutoEventLogger.sol";

contract DeployAutoEventLogger is Script {
function run() external {
vm.startBroadcast();

AutoEventLogger autoEventLogger = new AutoEventLogger();

// Example usage
autoEventLogger.logAction("Deployed contract");

vm.stopBroadcast();
}
}
20 changes: 20 additions & 0 deletions packages/auto-evm-storage/script/DeployAutoKeyValue.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/AutoKeyValue.sol";

contract DeployAutoKeyValue is Script {
function run() external {
vm.startBroadcast();

AutoKeyValue autoKeyValue = new AutoKeyValue(msg.sender);

// Set a key-value pair
autoKeyValue.setValue("exampleKey", "exampleValue");

// Retrieve the value for the key
autoKeyValue.getValue("exampleKey");

vm.stopBroadcast();
}
}
Empty file.
22 changes: 22 additions & 0 deletions packages/auto-evm-storage/script/DeployAutoMultiMap.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/AutoMultiMap.sol";

contract DeployAutoMultiMap is Script {
function run() external {
vm.startBroadcast();

AutoMultiMap autoMultiMap = new AutoMultiMap(msg.sender);

// Example usage
bytes32 key = keccak256(abi.encodePacked("exampleKey"));
bytes32 value1 = keccak256(abi.encodePacked("value1"));
bytes32 value2 = keccak256(abi.encodePacked("value2"));
autoMultiMap.addValue(key, value1);
autoMultiMap.addValue(key, value2);

vm.stopBroadcast();
}
}
22 changes: 22 additions & 0 deletions packages/auto-evm-storage/script/DeployAutoStackQueue.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";
import "../src/AutoStackQueue.sol";

contract DeployAutoStackQueue is Script {
function run() external {
vm.startBroadcast();

AutoStackQueue autoStackQueue = new AutoStackQueue(msg.sender);

// Example usage
autoStackQueue.push(1);
autoStackQueue.push(2);

autoStackQueue.enqueue(10);
autoStackQueue.enqueue(20);

vm.stopBroadcast();
}
}
43 changes: 43 additions & 0 deletions packages/auto-evm-storage/src/AutoEnumerableMap.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/AccessControl.sol";

contract AutoEnumerableMap is AccessControl {
bytes32 public constant WRITER_ROLE = keccak256("WRITER_ROLE");

mapping(bytes32 => bytes32) private map;
bytes32[] private keys;

event KeyValueSet(bytes32 indexed key, bytes32 value);

constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}

function set(bytes32 key, bytes32 value) public {
require(
hasRole(WRITER_ROLE, msg.sender),
"Access denied: No write permissions"
);

if (map[key] == bytes32(0)) {
keys.push(key);
}

map[key] = value;
emit KeyValueSet(key, value);
}

function get(bytes32 key) public view returns (bytes32) {
return map[key];
}

function getKeys() public view returns (bytes32[] memory) {
return keys;
}

function grantWriterRole(address account) public onlyRole(DEFAULT_ADMIN_ROLE) {
grantRole(WRITER_ROLE, account);
}
}
38 changes: 38 additions & 0 deletions packages/auto-evm-storage/src/AutoEventLogger.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract AutoEventLogger {
struct Event {
address user;
string action;
uint256 timestamp;
}

Event[] public events;

event ActionLogged(address indexed user, string action, uint256 timestamp);

function logAction(string memory action) public {
Event memory newEvent = Event({
user: msg.sender,
action: action,
timestamp: block.timestamp
});

events.push(newEvent);
emit ActionLogged(msg.sender, action, block.timestamp);
}

function getEvents() public view returns (Event[] memory) {
return events;
}

function getEvent(uint256 index) public view returns (Event memory) {
require(index < events.length, "Invalid index");
return events[index];
}

function getEventsCount() public view returns (uint256) {
return events.length;
}
}
58 changes: 58 additions & 0 deletions packages/auto-evm-storage/src/AutoKeyValue.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/AccessControl.sol";

contract AutoKeyValue is AccessControl {
bytes32 public constant WRITER_ROLE = keccak256("WRITER_ROLE");
bytes32 public constant EDITOR_ROLE = keccak256("EDITOR_ROLE");

mapping(string => string) private store;

event KeyValueSet(string indexed key, string value);

constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}

function setValue(string memory key, string memory value) public {
require(
hasRole(WRITER_ROLE, msg.sender) || hasRole(EDITOR_ROLE, msg.sender),
"Access denied: No write permissions"
);
store[key] = value;
emit KeyValueSet(key, value);
}

function getValue(string memory key) public view returns (string memory) {
return store[key];
}

function grantWriterRole(address account) public onlyRole(DEFAULT_ADMIN_ROLE) {
grantRole(WRITER_ROLE, account);
}

function grantEditorRole(address account) public onlyRole(DEFAULT_ADMIN_ROLE) {
grantRole(EDITOR_ROLE, account);
}

function setMultipleValues(string[] memory keys, string[] memory values) public {
require(keys.length == values.length, "Keys and values arrays must have the same length");
require(
hasRole(WRITER_ROLE, msg.sender) || hasRole(EDITOR_ROLE, msg.sender),
"Access denied: No write permissions"
);
for (uint i = 0; i < keys.length; i++) {
store[keys[i]] = values[i];
emit KeyValueSet(keys[i], values[i]);
}
}

function getMultipleValues(string[] memory keys) public view returns (string[] memory) {
string[] memory values = new string[](keys.length);
for (uint i = 0; i < keys.length; i++) {
values[i] = store[keys[i]];
}
return values;
}
}
Loading
Loading