decrypto-org / blockchain-course

An interactive course on blockchain science and engineering
MIT License
14 stars 11 forks source link

CircleCI

Introduction to Blockchains

This repository contains the material for our Introduction to Blockchains course.

You can take the course online at blockchain-course.org.

Installation

Full

This installation needs a database to function correctly. Any database will do. We provide here instructions for setting up and using Postgres.

CLI (without database)

Assignment creation and testing do not need a database management system (DBMS). Please note that CLI commands such as get user or stats top still need a DBMS and you should follow the full installation instructions.

Environment variables

Database

DB_URI: Postgres connection URI. It has the following format DB_URI=postgres://user:password@host/database. See more at Connection URIs.

PROVIDER: An Ethereum provider like ganache-cli. Needed by SolidityJudge.

ASSIGNMENT_FOLDER: The path of the folder that contains the assignments. Defaults to db/assignments.

API

GITHUB_CLIENT_ID: Your Github Client ID. See more at Building OAuth Apps.

GITHUB_CLIENT_SECRET: Your Github Client Secret. See more at Building OAuth Apps.

GITHUB_CALLBACK_URL: Authorization callback URL. See more at Redirect URLs.

APP_SECRET: Session secret. See more at express-session.

APP_URL: The URL of the web app.

PORT: API server port.

APP

REACT_APP_API_URL = The URL of the API server.

REACT_APP_LOGIN_URL = The API login URL.

PORT: APP web server port. Needed only for development.

Assignments

Assignments by default are assumed to be inside db/assignments. You can change the location of the assignment folder by setting the environment variable ASSIGNMENT_FOLDER.

Each assignment should extend the BaseJudge class or the SolidityJudge class in the case of the smart contract. The assignments are parameterized for each user and each user has a public and a private aux. Both the public and the private aux are created once (See db/models/parameterizedassignment.js).

Each assignment has to implement judge (aux, user, assignment, solution) and aux (user, assignment) functions. judge function takes as input an aux, a user, an assignment and a solution, and returns an object containing the grade and a message to show to the user. The return object's format must be: { grade: 0, msg: 'A message' } The aux function takes as input the user and the assignment and returns an aux { private: privateAux, public: publicAux } where private and public can be of any type and can be omitted.

Example

const BaseJudge = require('../judge/BaseJudge')
const { sha256 } = require('../helpers')

const PREIMAGE_PREFIX = 'blockchain-course.org:'
const POW_TARGET = 5

class ProofOfWorkAssignmentJudge extends BaseJudge {
  aux (user, assignment) {
    return {
      public: user.id
    }
  }

  async judge (aux, user, assignment, solution) {
    const nonce = solution
    if (sha256(PREIMAGE_PREFIX + aux.public + nonce).substr(0, POW_TARGET) === '0'.repeat(POW_TARGET)) {
      return { grade: 1, msg: 'Congratulations! Solution correct.' }
    }
    return { grade: 0, msg: 'Wrong! Please try again.' }
  }
}

ProofOfWorkAssignmentJudge.metadata = {
  lecture: 'cryptographic-primitives',
  name: 'proof-of-work',
  title: 'Performing Proof-of-Work',
  description: `Find a nonce such that the hexadecimal digest of SHA256("${PREIMAGE_PREFIX}" || "%s" || <nonce>) starts with ${POW_TARGET} zero characters`,
  type: BaseJudge.type.TEXT
}

module.exports = ProofOfWorkAssignmentJudge

Development

Build APP

Serve API

CLI Usage

The CLI provides various functionalities to aid in the development of exercises, without the need of API or APP deployment, and provide useful statistics. If only want to create and test assignments you do not need to install any DBMS.

Usage

node cli.js <command>

Commands:
  cli.js generate <command>  Generate <aux>
  cli.js get <command>       Get an entity <assignment>
  cli.js judge <id>          Judge a solution for a specific assignment
  cli.js stats <command>     Get user stats <top|last|score>

Options:
  --version  Show version number                                       [boolean]
  --help     Show help                                                 [boolean]

Examples

node cli.js generate aux proof-of-work
node cli.js generate aux proof-of-work --user.id=2 --user.username='foo'
node cli.js judge proof-of-work --solution 'a_solution' --aux.public=2
node cli.js judge simple-storage --solution=/Users/username/SimpleStorage.sol --file