GithubHelp home page GithubHelp logo

karminer's Introduction

Karminer

Las sospechas de corrupción por parte de los mantenedores de HAM nos han obligado a implementar una solución con la tecnología Blockchain para registrar el karma de cada individuo.

Cada grupo debe implementar un nodo minero usando TDD.

Básicamente un minero deberá:

  • escuchar nuevas transacciones, validarlas e intentar minarlas.
  • escuchar nuevos bloques, validarlos y actualizar los balances.

Se usarán funciones criptográficas de curva elíptica, se recomienda usar la gema bitcoin-ruby para esto.

Scafolding

# Install dependencies
brew bundle install
bundle install

# Run tests with guard
guard

Protocolo

Proveeremos un servidor pubsub a los que se conectaran los nodos/mineros

52.55.173.152:6379

Para conectarse se recomienda usar la gema redis

redis = Redis.new(url: "redis://52.55.173.152:6379")

# para escuchar:

redis.subscribe("pagos") do |on|
  on.message do |channel, message|
    pago = JSON.parse(message)
  end
end

redis.subscribe("bloques") do |on|
  on.message do |channel, message|
    bloque = JSON.parse(message)
  end
end

# para enviar bloques

redis.publish 'bloques', [{ ... }, { ... }].to_json

Existirán 2 canales:

pagos: los eventos corresponden a nuevas transacciones

{
  "de": "0xABCD",       // llave pública compacta del que manda
  "nonce": 0,           // nonce del pago, debe ser mayor al último nonce de `pago.de`
  "para": "0xABCD",     // llave pública compacta del que recibe
  "karma": 123,         // monto entero
  "piticlines": 1,      // propina pal minero
  "firma": "0xABCD"     // firma_ec_compacta(SHA256("{de}{para}{piticlines}"), llave_privada_del_que_manda)
}

Para el cálculo de la firma en ruby se puede usar la gema bitcoin-ruby (ya incluida en el proyecto):

Bitcoin::OpenSSL_EC.sign_compact(Digest::SHA256.digest("{de}{para}{piticlines}"), llave_privada_hex)

bloques: los eventos corresponden a nuevos estados del blockchain completo (cada vez que hay un nuevo bloque)

[
  ...,
  {
    "hash_anterior": "0xABCD",  // hash bloque anterior
    "pago": {
      // pago minado
    },
    "numerito": 133,            // numerito Proof of Work
    "minero": "0xABCD",         // llave pública compacta del minero que minó, aquí se abona la recompensa + la propina
    "hash": "0xABCD"            // SHA256("{hash_anterior}{hash_pago}{minero}{numerito}")
  }
]

Reglas

  1. Toda 'dirección' parte con 1000 de Karma.

  2. Se deben validar un pago antes de minarlo.

2.1. Se debe validar que pago.karma + pago.piticlines > balance(pago.de).

2.2. Se debe validar que pago.nonce > ultimo_nonce(pago.de).

2.3. Se debe validar que recover_compact(pago.firma, SHA256("{de}{para}{piticlines}") == pago.de.

2.4. Para minar un pago se debe encontrar un numerito tal que

base58(SHA256("{bloque.hash_anterior}{hash_pago}{bloque.minero}{bloque.numerito}")).donwcase.end_with?('frog')

Donde hash_pago = SHA256("{de}{para}{piticlines}")

  1. Cada vez que llega una actualización del bloque, se deben procesar los bloques nuevos (bloques después del último bloque conocido). Si el hash del último bloque conocido no se conoce y la cadena es más larga que la conocida, entonces se debe validar desde el bloque 0.

  2. Cada vez que llega una actualización del bloque, por cada bloque nuevo (bloques después del último bloque conocido)

4.1 Se debe validar que bloque.pago sea válido (según 2, 3, 4 )

4.2 Se debe validar que bloque.hash esté correctamente calculado según 2.4.

4.3 Se debe validar que bloque.hash_anterior sea igual al último hash de un bloque válido (o 0x0 si es el primer bloque).

  1. Cada vez que se recibe un bloque válido

5.1 Se debe restar pago.karma + pago.piticlines a balance(pago.de)

5.2 Se debe sumar pago.karma a balance(pago.para)

5.3 Se debe sumar pago.piticlines a balance(bloque.minero)

5.4 Se debe actualizar el último bloque válido

5.5 Si se está minando se debe reemplazar el hash_anterior por el hash del nuevo bloque obtenido.

5.6 Si se está minando se debe revisar que el pago que está siendo minado no corresponde al pago del bloque recién minado.

  1. Cada vez que se recibe un bloque inválido se debe mostrar el address del minero que intentó empujarlo.

Aclaraciones

Cada nodo deberá mostrar en todo momento el balance de todas las cuentas que conoce.

Las transacciones serán gatilladas ‘a mano’ por los usuarios roñosos.

karminer's People

Contributors

blackjid avatar iobaixas avatar llekn avatar

Watchers

 avatar  avatar  avatar

Forkers

llekn

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.