Cooperative databases using smart contracts.

Overview

Vitra

██╗   ██╗██╗████████╗██████╗  █████╗
██║   ██║██║╚══██╔══╝██╔══██╗██╔══██╗
██║   ██║██║   ██║   ██████╔╝███████║
╚██╗ ██╔╝██║   ██║   ██╔══██╗██╔══██║
 ╚████╔╝ ██║   ██║   ██║  ██║██║  ██║
  ╚═══╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝

Cooperative databases using smart contracts. Read the white paper.

Introduction

Vitra is a research project for exploring the limits of smart contracts without blockchains -- specifically, without using decentralized consensus algorithms like Proof-of-Work or Proof-of-Stake. Its purpose is research and education. Contributors are welcome, but the software is not stable and should not be used in production.

Overview

Vitra is a hybrid of blockchains and traditional databases. It takes inspiration from Certificate Transparency and Layer 2 Optimistic Rollups to create a hosted smart-contract protocol called "Execution Transparency (ET)."

Vitra databases use verifiable logs to record all transactions in a publicly-auditable structure. A contract written in Javascript then enforces the schemas and business logic of the database. By replaying the logs, users can audit the execution of the database and ensure that each participant is playing by the rules. Vitra also responds to every transaction with an inclusion proof, giving end-users an efficient solution to proving their data in the database.

When is this useful?

  • Public/community services that need to publish very sensitive data, like user encryption-keys or software packages. Vitra gives clear external auditability of every change that occurs, much like Certificate Transparency does for PKI.
  • Decentralized organizations where a database needs to be shared among people who don't totally trust each other. The smart contract ensures that the operator of the database can't cheat the community; it effectively protects users from the owners of a service.
  • Large multi-org collaborations (think enterprises with multiple vendors) where data-sharing needs to be coordinated and consistent. Vitra protects you from incompetance in the same way it protects you from malice: the system is transparent and self-auditing.

Vitra uses the Hypercore Protocol to implement its verifiable logs.

Tutorial video

Watch the tutorial video here.

Vitra tutorial video

Docs

Example

This very simple contract maintains a counter which can only ever increment. The contract exports two calls, get() and increment({amount}), which we can use to interact with the database.

/**
 * Counter
 *
 * This contract maintains a singe numeric value which can only be incremented. 
 */

import { index } from 'contract'

// database api
// =

export async function get () {
  const entry = await index.get(`/counter`)
  return Number(entry?.value || 0)
}

export function increment (opts = {}, emit) {
  const amount = typeof opts?.amount === 'number' ? opts.amount : 1
  emit({op: 'INCREMENT', amount})
}

// transaction handler
// =
 
export const apply = {
  async INCREMENT (tx, op) {
    const current = await get()
    tx.put(`/counter`, current + op.amount)
  }
}

You'll notice that transactions are handled in two phases: first publishing an operation with emit(), and then applying the operation with apply.INCREMENT(). This separation is because Vitra databases may have multiple participants who can generate ops, but only one executor who can execute the ops. When we verify a contract, we're replaying the emitted operations against the apply functions to make sure the executor has been honest.

Let's create a database using our contract. We'll use the API for this readme, but the interactive CLI is generally much easier.

import { Database } from 'vitra'

// Create the DB
const db = await Database.create('./db-storage-path', {
  contract: {source: COUNTER_CONTRACT}
})
db.swarm() // share on the hypercore network
console.log('New database created, public key:', db.pubkey.toString('hex'))

// Read the current state
const tx1 = await db.call('get', {})
console.log(tx.response) // => 0

// Increment a few times
const tx2 = await db.call('increment', {})
const tx3 = await db.call('increment', {amount: 2})
const tx4 = await db.call('increment', {})

// Wait for those increments to be processed
await Promise.all([tx2.whenProcessed(), tx3.whenProcessed(), tx4.whenProcessed()])

// Read the new state
const tx5 = await db.call('get', {})
console.log(tx.response) // => 4

As you can see, Vitra is a programmable database. We're interacting with the DB using the contract's API.

To verify the execution, we can use one of two methods: verify() or monitor(). The difference is whether we want to persistently verify or not; monitor will watch for new updates and verify them continuously.

await db.verify() // check all current state

const mon = await db.monitor() // persistently monitor transactions
mon.on('violation', console.log)

Generally we try not to violate a contract; violations are unrecoverable and will require users to switch to an entirely new database. This is on purpose: if a contract has been violated, then your database's executor has either suffered a serious technical issue, or they're trying to defraud you and shouldn't be trusted!

For this example, however, we'll force a violation to see what happens:

await db.index.dangerousBatch([{type: 'put', path: '/counter', value: 1}])

try {
  await db.verify()
} catch (e) {
  console.log(e) // => ContractFraudProof (The executor has violated the contract)
}

We just violated the contract by setting the counter back to 1. This particular violation is an unprompted change -- no operation caused this write -- but if the executor had responded to an operation with the wrong changes, or skipped over an operation, or tried to unpublish a change, it would be caught the same way.

License

Vitra is copyright 2022 Blue Link Labs. We're currently deciding how to license Vitra and have not set a FOSS license yet, though we intend to (sorry!). We're currently considering a less liberal license such as AGPL.

Future improvements

Transaction-result inclusion proofs

Calls to a contract (transactions) may produce one or more operations, and each operation may produce one or more changes (results). Operations are published by the contract participants by writing to their "oplogs," while the operation results are always published by the executor in the "index log." Using Hypercore, we're able to generate inclusion proofs for any log message.

Inclusion proofs are comprised of a log message's sequence number, the root hash of the log's merkle tree, and a signature over the root hash by the log's keypair. We can use the inclusion proof to independently verify that a log message was published by a log, and to prove mischief if the log owner ever attempts to unpublish a message.

Vitra can easily generate an inclusion proof for operations when handling a transaction because there's a local interactive session with the participant that's executing the transaction. For the results published to the index log, there's no guarantee of an interactive session as the participant may not be the executor. The Hypercore protocol has mechanisms for requesting log inclusion proofs over a connection (this is fundamental to the protocol) but the implementation embeds this in the replication logic and does not currently include APIs to fetch proofs for random messages in a log. By adding those APIs to Hypercore, we can add transaction-result inclusion proofs to Vitra's API.

Additional append-only fraud proof detection

Violations to the append-only constraint are currently detected when verifying an inclusion proof. It is possible to detect append-only violations more aggressively by checking for them during replication. (In this framework, forking explicitly with Hypercore's truncate() API and forking implicitly with split logs are both considered violations.)

Native-code contract runtime

Currenly Vitra is using [https://github.com/laverdet/isolated-vm] to execute contracts (via the Confine Sandbox framework). This could be optimized by replacing the Confine guest process with a C++ program that embeds V8, which would reduce the amount of marshalling between V8 contexts.

Edge-case protocols

Vitra is currently designed to follow the contract with no external mutations allowed. This means that operator error could leave a Vitra in an unrecoverable state. We could solve this kind of problem with "edge-case protocols." Some edge-case protocols to consider:

  • Contract rollback. A broken contract could leave the database in an inoperable state (e.g. a runtime error stops execution). An edge-case protocol for rolling back to a previous version could help solve this.

ZK-SNARKs

Vitra uses transaction logs and log-replays to audit execution of a database. Novel research in Layer 2 rollups has recently focused on using zero-knowledge proofs to create a more compact and efficient approach to auditing (ZK-Rollups). It should be possible to apply the same research to Vitra.

You might also like...

🚀 NFTank (NFT tank for dummies) will allow developers to quickly request NFTs to personal wallets or smart contracts in just a few clicks.

🚀 NFTank (NFT tank for dummies) will allow developers to quickly request NFTs to personal wallets or smart contracts in just a few clicks.

👷‍♂️ NFTank 🚀 NFTank (NFT tank for dummies) will allow developers to quickly request NFTs to personal wallets or smart contracts in just a few click

Nov 8, 2022

Toolkit for development, test and deploy smart-contracts on Waves Enterprise ecosystem.

JS Contract SDK Toolkit for development, test and deploy smart-contracts on Waves Enterprise ecosystem. Quickstart The fastest way to get started with

Dec 15, 2022

A simple project to learn more about developing smart contracts on polygon.

polygon-books-hardhat A simple project to learn more about developing smart contracts using Solidity. Local Development Environment Setup Install all

Jan 25, 2022

Cardinal generator encompasses serverless functions and smart contracts for rendering generative NFTs

Cardinal generator encompasses serverless functions and smart contracts for rendering generative NFTs

Cardinal Generator An open protocol for generative NFTs. Background Cardinal generator encompasses serverless functions and smart contracts for render

Dec 6, 2022

A Typescript Hardhat-based template to develop evm-based smart contracts with all the tooling you need.

EVM-based Smart Contract Scaffold A Typescript Hardhat-based template to develop evm-based smart contracts with all the tooling you need. Features Use

Oct 24, 2022

Elrond blockchain CLI helper tools - interaction with APIs, smart contracts and protocol

Buildo Begins 👷 Meet Buildo. He is here to help you start creating in the Elrond blockchain ecosystem. Here is where everything begins. I'm going on

Dec 30, 2022

This is a CI/CD and version controlling tool for smart contracts which is an award winning project built for ETHPrague Hackaton.

This is a CI/CD and version controlling tool for smart contracts which is an award winning project built for ETHPrague Hackaton.

Inspiration Alfred is built-in version control and CI/CD system for your smart contracts. It uses proxy contract and a DAO to upgrade or downgrade you

Aug 30, 2022

🦠🔬 Forta agent that detect deployment of smart contracts containing an exploit function

Attack Simulation Bot Description The agent detects deployment of smart contracts containing an exploit function. Using a simulation-based approach, t

Dec 26, 2022

🌳📝 Smart contracts for the Arbor Protocol

Arbor Smart Contracts app testnet landing docs discord blog twitter Security Please report any security issues to [email protected] V1 Smart Contr

Nov 21, 2022
Comments
Owner
Paul Frazee
https://twitter.com/pfrazee
Paul Frazee
♦ Crowd funding project using Smart Contracts on the Ethereum. Created with Next.js and Tailwind CSS.

Crowdcoin ♦ Crowd funding project using Smart Contracts on the Ethereum. Created with Next.js and Tailwind CSS. Project from "Ethereum and Solidity: T

Luiz Fernando Veríssimo 2 Dec 14, 2022
Using a Decentralized Application (DApp) to Sell artwork on the Ethereum blockchain with smart contracts written in Solidity.

Decentralized Applications For Selling Limited Time Artwork This repository houses the Solidity, JavaScript, and HTML code for a Decentralized Applica

Keyan Ahmadi 4 Mar 20, 2023
A collection of smart contracts for the Stackup platform 🤖 📑

Contracts A collection of smart contracts for the Stackup platform. Dev Blog Deployed Contracts See releases for deployed contracts of previous versio

Stackup 16 Nov 29, 2021
Ethereum Smart Contracts for locking your Ether and ERC20 tokens based on time and price conditions

SmartHold - a simple way to lock and hold your ETH or ERC20 in a smart contract This is a BETA software that has not been audited for security. USE AT

Paweł Urbanek 22 May 5, 2022
Run CosmWasm smart contracts in Node.js and web browsers

Run CosmWasm smart contracts in Node.js and web browsers

Terran One 31 Nov 25, 2022
A 'to do list' powered by Ethereum smart contracts

A 'to do list' powered by Ethereum smart contracts. built with JavaScript, Ganache, Truffle, Node.js, Metamask, jQuery, and Bootstrap

Christotle Agholor 3 Feb 17, 2022
Context-aware smart contracts for blockchain IoT systems

Context-aware smart contracts for blockchain IoT systems It contains 2 directories: contracts: contains the ContextAwareSmartContract.sol contract wit

ibelab 6 Jun 17, 2022
This is the main repository for NFT collection dao smart contracts.

Basic Sample Hardhat Project This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample s

null 3 Apr 11, 2022
Yet another library for generating NFT artwork, uploading NFT assets and metadata to IPFS, deploying NFT smart contracts, and minting NFT collections

eznft Yet another library for generating NFT artwork, uploading NFT assets and metadata to IPFS, deploying NFT smart contracts, and minting NFT collec

null 3 Sep 21, 2022
a quick start boilerplate for developing web3 apps and deploying smart contracts.

create-web3 A boilerplate for starting a web3 project. This boilerplate quickly creates a mono repo with 2 environments, a Next JS environment for fro

Eric Roupe 83 Dec 16, 2022