Skip to content

Instantly share code, notes, and snippets.

@deemp
Last active December 15, 2022 09:42
Show Gist options
  • Save deemp/33df2048c69bf28c4701362fdc388060 to your computer and use it in GitHub Desktop.
Save deemp/33df2048c69bf28c4701362fdc388060 to your computer and use it in GitHub Desktop.
Database-like contract using solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Database {
struct Table {
string[] columns;
mapping(string => string[]) values;
bool exists;
}
mapping(string => Table) table;
mapping(string => bool) has;
function contains(
string[] memory a,
string[] memory b
) private returns (bool) {
for (uint i = 0; i < b.length; i++) {
has[b[i]] = false;
}
for (uint i = 0; i < a.length; i++) {
has[a[i]] = true;
}
bool contains_ = true;
for (uint i = 0; i < b.length; i++) {
contains_ = contains_ && has[b[i]];
}
return contains_;
}
function CREATE_TABLE(string memory a, string[] memory b) public {
table[a].columns = b;
table[a].exists = true;
}
function DROP_TABLE(string memory a) public {
delete table[a];
}
mapping(string => string) toInsert;
function INSERT(
string memory tableName,
string[] memory columns_,
string[] memory values_
) public {
require(table[tableName].exists, "No such table");
require(columns_.length == values_.length, "Mismatched #columns and #values");
require(contains(table[tableName].columns, columns_), "No such columns");
string[] memory tableColumns = table[tableName].columns;
for (uint i = 0; i < tableColumns.length; i++) {
toInsert[tableColumns[i]] = "";
}
for (uint i = 0; i < columns_.length; i++) {
toInsert[columns_[i]] = values_[i];
}
for (uint i = 0; i < tableColumns.length; i++) {
table[tableName].values[tableColumns[i]].push(toInsert[tableColumns[i]]);
}
}
mapping(string => string[]) selectResult;
function SELECT(
string memory tableName,
string[] memory columns_
) public returns (string[][] memory) {
require(table[tableName].exists, "No such table");
require(
contains(table[tableName].columns, columns_),
"No such columns"
);
uint size = columns_.length;
string[][] memory res = new string[][](size);
for (uint i = 0; i < columns_.length; i++) {
res[i] = table[tableName].values[columns_[i]];
}
return res;
}
}
import { ethers } from "hardhat";
async function main() {
const Database = await ethers.getContractFactory("Database")
const accounts = await ethers.getSigners()
const owner = accounts[0]
console.log(`Database admin: ${owner.address}`)
const db = await Database.deploy()
console.log(`Database address: ${db.address}`)
await db.CREATE_TABLE("films", ["title", "year"])
await db.INSERT("films", ["title", "year"], ["TBD", "TBD"])
await db.INSERT("films", ["title"], ["TBD"])
const data1 = (await db.SELECT("films", ["title"])).data
const data = db.interface.decodeFunctionData("SELECT", data1)
console.log(data)
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment