Plasma Cash Chain como solución al trilema de escalabilidad de blockchain

Buenas tardes, queridos lectores!

Este artículo trata sobre la cadena de efectivo de plasma y arroja luz sobre los siguientes temas:

  • el trilema de escalabilidad y los métodos para su solución;
  • estructuras de datos de la cadena secundaria y su visualización en la cadena raíz;
  • implementación de entrada a la cadena raíz;
  • implementación de la retirada de la cadena raíz.

Opporty utilizó el lenguaje de programación Javascript para implementar la cadena secundaria, así como Solidity para la cadena raíz. Se proporcionan ejemplos de código en estos idiomas.



Blockchain y la descentralización permiten optimizar y mejorar el trabajo de casi cualquier esfera de la vida donde se utilizan Internet y las tecnologías de la información. Aumentan la fiabilidad, la eficiencia financiera y también facilitan la digitalización de bienes y bienes reales.

Los contratos inteligentes llevan la lógica empresarial a las redes descentralizadas. Esto le permite crear nuevas aplicaciones DAPP.

La ejecución de contratos inteligentes y la operación rápida de aplicaciones con una base de datos distribuida solo puede ser posible si se cumple la condición de escalabilidad.

Las cadenas de bloques modernas descentralizadas tienen varios inconvenientes. El principal es la escalabilidad. Ethereum procesa alrededor de 20 tx / s. Esto no es suficiente en las realidades financieras modernas. Al mismo tiempo, Ethereum tiene el mayor grado posible de protección contra piratería y fallas en la red. Otras criptomonedas y sistemas construidos en blockchain no tienen un grado tan alto de descentralización, lo que reduce la confianza en la red.

El trilema de escalabilidad


Existe un trilema de escalabilidad de blockchain que incluye tres componentes:

  • descentralización;
  • seguridad
  • escalabilidad

Descentralización en el trilema


La descentralización, como su término lo indica, refleja el grado de diversificación de la propiedad de la actividad en la cadena de bloques, así como el grado de diversificación de crear bloques y generar nuevas entradas en el libro mayor.

Para mayor claridad, es necesario hablar sobre las organizaciones más centralizadas. Por lo general, se usa una base de datos simple en lugar de blockchain. Dicha organización está dirigida por administradores especiales. Todas las transacciones pueden cancelarse mediante intervención manual.

En redes totalmente descentralizadas, cada usuario puede participar en la construcción de una red.

La consecuencia más importante de la descentralización es que la mayor parte del valor va a la comunidad que participa en la creación de la cadena de bloques. No existe un equipo intermedio de gerentes que reciba todos los beneficios en lugar de aquellos que generan la estructura de la red en sí. De hecho, la mayoría de los proyectos criptográficos son propiedad exclusiva de sus contribuyentes o usuarios, no de los fundadores. Obviamente, este es un modelo más atractivo para quienes no son fundadores.

Seguridad en el trilema


Se trata de la capacidad de blockchain para resistir ataques de fuentes externas y mantener el sistema en un estado sin cambios. La mayoría de las cadenas de bloques están sujetas a muchas amenazas potenciales de seguridad. Es imprescindible conocer los vectores de ataque y las opciones de defensa más comunes.

En este caso, la descentralización y la seguridad van de la mano. Cuantos más nodos, menos depende la red del lado centralizado y, por lo tanto, del riesgo de tener un punto central de falla. Sin embargo, hay muchos otros vectores de ataque que representan una amenaza para las redes descentralizadas, que incluyen:
> 50% de ataque : un objeto que posee más del 50% del número total de tokens no pagados en realidad posee la red;
> Sybil Attack : el usuario puede generar muchos identificadores en el sistema para controlar efectivamente una parte importante de la propiedad y / o la toma de decisiones en la red;
> DDoS : se produce un ataque de denegación de servicio distribuido (DDoS) cuando existe la intención de interrumpir el tráfico en la red, llenando la red con transacciones maliciosas;
> Ataque de colusión : uno o más objetos (o nodos) deciden unirse para realizar cualquier operación maliciosa en la red.

Escalabilidad en el trilema


El grado de escalabilidad es importante porque determina el rendimiento final, en otras palabras, el límite superior del tamaño de la red. La pregunta más importante que debe hacerse al evaluar una red es: "¿Cuántos usuarios puede soportar este sistema?" Bitcoin actualmente tiene entre 2,9 y 5,8 millones de titulares de billetera. EOS tiene varios miles de miembros.

La escalabilidad y la descentralización pueden coexistir, pero la seguridad se reduce. Los desarrolladores eligen las plataformas que mejor se adaptan a sus necesidades. Los usuarios hacen lo mismo. Las opiniones de las dos partes a veces difieren. Algunos usuarios están dispuestos a sacrificar la seguridad por la escalabilidad, otros están dispuestos a sacrificar la escalabilidad por la seguridad, pero el equilibrio es mucho más difícil.

"Santo Grial" en la tecnología blockchain


Por definición, una cadena de bloques tiene solo dos de las siguientes tres propiedades:

  • Descentralización (cada participante tiene acceso solo a recursos O ©, es decir, a una computadora portátil normal o un VPS pequeño);
  • Escalabilidad (capacidad de procesar transacciones O (n)> O ©);
  • Seguridad (protección contra intrusos que utilizan recursos O (n)).


Verde: un estado equilibrado de tres condiciones.
Rojo: seguridad fuerte pero descentralización y escalabilidad limitadas.
Azul: la eficiencia es alta, pero la seguridad y la descentralización son limitadas.
Negro: la descentralización es alta, pero no hay aspectos de escalabilidad y seguridad.
Gris: descentralización total, con cualidades mínimas o faltantes de seguridad y escalabilidad.
Violeta: un equilibrio igual entre seguridad y escalabilidad, el rechazo de la descentralización.

El "santo grial" en la tecnología blockchain significa combinar los tres aspectos.
En la mayoría de los proyectos actuales que trabajan con criptomonedas, se logran dos propiedades básicas: descentralización y seguridad. La escalabilidad sufre.

Soluciones prometedoras al trilema


Prueba de estaca (PoS)


Proof of Stake (PoS) proporciona mejoras potenciales de escalabilidad. POS reemplaza la minería de criptomonedas basada en el sistema de Prueba de trabajo (PoW). La elección del validador es muy rápida, de manera determinista. Al mismo tiempo, no hay costo de energía y es ecológico.

Cadenas laterales


En la red virtual Ethereum, existe la posibilidad de crear una red secundaria en la que el proyecto pueda procesar sus transacciones individuales y luego registrar solo los resultados iniciales y finales en la red Ethereum. Esto reduce la carga en el EVM, pero da más confianza en la gestión de la cadena lateral. Por lo tanto, la confianza en un tercero reduce la descentralización.

Sharding


El fragmentación divide las transacciones en piezas de datos más pequeñas. En lugar de que cada nodo individual en la red procese transacciones completas, los nodos se dividen en grupos, y estos grupos de nodos procesan ciertos datos. Más tarde, durante el procesamiento, estos datos se vuelven a asimilar para el almacenamiento permanente en la cadena de bloques.

Aumentar el tamaño del bloque


Litecoin y Bitcoin Cash (BCH) son "tenedores" para la cadena de bloques de Bitcoin. Bifurcación básicamente copia una cadena de bloques. Después de ramificarse, puede hacer cambios. Tanto LTC como BCH aumentaron el tamaño de cada bloque, lo que permitió almacenar más transacciones por bloque, aumentando así la velocidad de procesamiento de las transacciones.

Red de rayos


La primera solución de cadena lateral fue un rayo. La idea principal de Lightning Network es que no todas las transacciones deben registrarse en la cadena de bloques, ya que esto sobrecarga la red. Si los usuarios transfieren fondos entre sí varias veces, entonces registrar cada transferencia es opcional. Basta con abrir una especie de canal de pago y anotar los datos sobre su apertura en la cadena de bloques. Este canal permanecerá abierto según sea necesario. Cuando sea necesario cerrarlo, el resultado de todas las transacciones realizadas en este canal simplemente se escribe en la cadena de bloques. Siguiendo esta idea, puede crear una red completa de canales para pagos. Luego, las transacciones en blockchain se usarán con mucha menos frecuencia.

Un canal de pago es solo una combinación de varias transacciones. Un canal puede ser cerrado por cualquiera de sus miembros. Esta acción será como abrir una caja fuerte, que le permite tomar los fondos que pertenecen a los participantes y anotar los datos de su transferencia a la cadena de bloques.
Esta tecnología se vuelve realmente poderosa cuando varios de estos canales se combinan en una red llamada The Lightning Network. Esta red está especialmente construida para Bitcoin.

Red Raiden


Para Ethereum, la contraparte más conocida de Lightning es la Red Raiden.
Esta es una solución para escalar fuera de la cadena de bloques principal. Es compatible con la transferencia de tokens ERC-20 en canales de pago bidireccionales.

Su arquitectura básica es compleja, pero la interacción con Raiden requiere que los desarrolladores solo interactúen con la API para crear aplicaciones escalables en Raiden.

Raiden está diseñado para proporcionar pagos instantáneos y bajas comisiones, aumentar la confidencialidad de las transacciones y los micropagos. La mayoría de los canales de pago existen fuera de la red y solo ocasionalmente forman transacciones dentro de la cadena raíz, lo que reduce significativamente el rendimiento de la cadena secundaria.

Solución óptima


Los ideólogos del rayo han creado un nuevo concepto de cadena infantil que resuelve los problemas de velocidad de la cadena de bloques.

Opporty prácticamente implementa el concepto de Plasma y Plasma Cash.

Plasma es un conjunto de contratos inteligentes que se ejecutan en la parte superior de la cadena raíz de Ethereum y consisten en una red de cadenas secundarias conectadas a la cadena raíz en una estructura de árbol jerárquica.

Es decir, la seguridad de la cadena raíz de Ethereum se utiliza para optimizar la escalabilidad.

Plasma Cash: Opción Opporty


Opporty utiliza la implementación de Plasma Cash en la primera versión.

Este modelo es la implementación de plasma más efectiva en términos de escalabilidad.
Plasma Cash es un sistema basado en el uso de identificadores únicos para cada token en la cadena de Plasma. Es decir, se aplica NFT y los tokens en la red reciben números de serie únicos.

Características del efectivo de plasma:

  • Validación fragmentada en el lado del cliente: los clientes solo necesitan monitorear su cadena de Plasma para obtener sus tokens. Esto significa que el rendimiento de la transacción puede aumentar sin aumentar la carga de los usuarios individuales.
  • Simplificación de la salida masiva: las salidas masivas se convierten en una amenaza menor para la red, ya que el ladrón debe enviar una transacción de salida por cada ficha que quiera robar.
  • No hay confirmaciones bidireccionales: las transacciones ya no requieren envío y confirmación en dos pasos. En cambio, una transacción se puede gastar tan pronto como se incluya en la cadena principal.

Desventaja

Grandes denominaciones de tokens: dado que a cada token se le debe asignar un número de serie, es imposible producir tokens arbitrariamente pequeños. Esto se debe al hecho de que en algún momento el valor de la compra del token será mayor que el valor del token en sí.

Estructura de la transacción en Opporty Plasma Cash


Opporty usó Javascript para implementar childchain. Cada transacción en Opporty Plasma Cash es una estructura similar:

const transactionFields = [ {name: 'prevHash'}, {name: 'prevBlock', int: true, default: 0}, {name: 'tokenId', isDecimal: true}, {name: 'newOwner'}, {name: 'type'}, {name: 'signature'}, ] 

Los elementos principales aquí son un enlace al bloque anterior prevBlock (se necesita para moverse por la cadena de bloques), el identificador de tokenId token (debe ser único) y también newOwner, el último propietario del token.

Además, para ensamblar el bloque y obtener el hash de la cadena de raíz, se usa un tipo especial de árbol Patricia Merkle Trie. El mismo árbol se usa en Ethereum. Tiene un aspecto comprimido. Al mismo tiempo, aún puede recibir pruebas de inclusión o no inclusión de una transacción en un bloque.
Firma es una firma en curvas elípticas.

Una transacción que gasta un token con un tokenId dado es válida solo si está incluida en el árbol Merkle en la posición tokenId, es decir, para cada token en el árbol Merkle solo hay un "lugar" que gasta este token donde se permiten transacciones. Este formato permite a los usuarios verificar el historial completo de la cadena Plasma, así como probar y refutar la propiedad de tokens específicos.

Para gastar un token, debe validar la cadena, verificar si faltan bloques y solo luego volver a firmar la transacción junto con todo el historial.

El bloque es el siguiente:

 const blockFields = [ {name: 'prevHash'}, {name: 'blockNum', isDecimal: true}, {name: 'transactions'}, {name: 'merkleRoot'}, {name: 'time'} ] 

En un nivel básico, una cadena de bloques es simplemente una cadena de bloques con un enlace al bloque anterior. Dicha estructura permite obtener la propiedad de inmutabilidad, es decir, no reescribir el historial. merkleRoot hace posible escribir puntos de control en la cadena raíz.

En la cadena raíz, en el nivel de contrato inteligente, se ve así (lenguaje de solidez):

 /* * Block structure (represents one block in a chain) */ struct Block { uint block_num; bytes32 merkle_root; uint time; /* * Transaction structure (decoded from RLP form) */ struct Transaction { bytes32 prevhash; uint prev_block; uint token_id; address new_owner; } 

La codificación se realiza utilizando las funciones de codificación / decodificación - serialización / deserialización RLP.

Formas de ingresar al efectivo de plasma


Cualquiera puede depositar fondos en Plasma Cash simplemente transfiriendo éter a un contrato inteligente. Como resultado, se recibirá un token OPP en una posición específica de tokenId.

Aquí está la implementación en Solidity:

 function deposit() public payable { uint token_id = uint(keccak256(msg.sender, msg.value, deposit_blk)); // token.index = deposit_blk; tokens[token_id] = msg.value; deposit_blk += 1; emit DepositAdded(msg.sender, msg.value, token_id, current_blk); } 

Es decir, tokenId se genera como un número aleatorio (hash). A continuación, se genera un evento que se escanea en la cadena secundaria.

Formas de retirarse a Plasma Cash


Cada persona puede retirar su token proporcionando las dos últimas transacciones en el historial de propiedad del token.

Implementación de salida de la cadena raíz:

 function startExit(uint block_num, bytes tx1, bytes tx0, bytes proof1, bytes proof0) public returns (uint exit_id) { require(checkPatriciaProof(keccak256(tx1), childChain[block_num].merkle_root, proof1)); bytes32 prev_hash; uint prev_blk; uint token_id; address new_owner; (prev_hash, prev_blk, token_id, new_owner,) = getTransactionFromRLP(tx1); require(msg.sender == new_owner); require(tokens[token_id] > 0); bytes32 hashPrevTx = keccak256(tx0); require(checkPatriciaProof(hashPrevTx, childChain[prev_blk].merkle_root, proof0)); require(prev_hash == hashPrevTx); Exit storage record = exitRecords[token_id]; require(record.block_num == 0); record.block_num = block_num; record.new_owner = msg.sender; record.prev_block = prev_blk; if (childChain[block_num].time > block.timestamp - week) record.priority = childChain[block_num].time; else record.priority = block.timestamp - week; exits.add(record.priority); exit_ids[record.priority].push(token_id); emit ExitAdded(msg.sender, record.priority, token_id); return token_id; } 

Primero, se verifican dos transacciones. Si el usuario actual es el propietario de la transacción, simplemente agregamos su salida a la estructura y dejamos dos semanas para la oportunidad de desafiar la salida.

La conclusión puede ser cuestionada de tres maneras:

  • Proporcionar confirmación de gasto en transacciones:

 function challengeSpent(uint exit_id, uint blk_num, bytes tx1, bytes proof) public { require(checkPatriciaProof(keccak256(tx1), childChain[blk_num].merkle_root, proof)); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); uint prev_block; uint token_id; (, prev_block , token_id, ) = getTransactionFromRLP(tx1); require(tokens[token_id] > 0); require(prev_block == record.block_num && record.block_num < blk_num); require(token_id == exit_id); exit_ids[record.priority].remove(exit_id); delete exitRecords[exit_id]; emit ExitChallengedEvent(exit_id); } 

Si hay una transacción que ya está gastando el token que se muestra, ¡tal retiro se cancelará!

  • Prueba de gastos de la transacción anterior:

 /* * Challenge exit by providing * a proof of a transaction spending P(C) that appears before C */ function challengeDoubleSpend(uint exit_id, uint blk_num, bytes tx1, bytes proof) public { require(checkPatriciaProof(keccak256(tx1), childChain[blk_num].merkle_root, proof)); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); // bytes32 prev_hash; uint prev_block; uint token_id; (, prev_block , token_id, ) = getTransactionFromRLP(tx1); require(tokens[token_id] > 0); // check if token double spent require(prev_block == record.prev_block && blk_num < record.block_num); // require(token_id == exit_id); exit_ids[record.priority].remove(exit_id); delete exitRecords[exit_id]; emit ExitChallengedEvent(exit_id); } 

Esta es la misma verificación que si el token se hubiera gastado antes del retiro. Primero, verifique si hay una transacción en el hash raíz. A continuación, eliminamos la salida si ya se ha gastado.

  • proporcionando una transacción en el historial de transacciones del token anterior.

Esta puede ser una historia incorrecta, por lo que debe confirmarla con una transacción secundaria:

 // */ function challengeInvalidHistory(uint exit_id, uint blk_num, bytes tx0, bytes proof) public { // check if proof is valid require(checkPatriciaProof(keccak256(tx0), childChain[blk_num].merkle_root, proof)); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); bytes32 prev_hash; uint token_id; (prev_hash, , token_id, ) = getTransactionFromRLP(tx0); //require(exit_id == token_id); require(tokens[token_id] > 0); // transaction should be before exit tx in history require(blk_num < record.block_num - 1); challenged[exit_id] = blk_num; emit ChallengedInvalidHistory(exit_id, token_id); } 

Llamar al primer y segundo script bloquea la salida de inmediato.

La llamada al tercer escenario se puede responder proporcionando un descendiente directo. Debe ser igual o anterior a la transacción principal.

 /* * Respond to invalid history challenge by providing * the direct child of C*, which must be either equal to or before P( C ) */ function respondChallenge(uint exit_id, uint blk_num, bytes childtx, bytes proof) public { require(challenged[exit_id] > 0); Exit memory record = exitRecords[exit_id]; require(record.block_num > 0); require(checkPatriciaProof(keccak256(childtx), childChain[blk_num].merkle_root, proof)); // get transaction from rlpencoded form bytes32 prev_hash; uint prev_block; uint token_id; (prev_hash, prev_block, token_id, ) = getTransactionFromRLP(childtx); // if direct child if (prev_block == challenged[exit_id] ) { if (blk_num <= record.prev_block && token_id == exit_id ) { delete challenged[exit_id]; emit ExitRespondedEvent(exit_id); } else { exit_ids[record.priority].remove(exit_id); delete exitRecords[exit_id]; emit ExitChallengedEvent(exit_id); } } } 

Es decir, si se recibe la transacción secundaria correcta, ¡la salida se disputa y permanece en la cola!
Después de construir parte del protocolo Opporty Plasma Cash, se llegó a la siguiente conclusión:
Este protocolo proporciona seguridad a través de la cadena raíz Ethereum.

Al complicar los procedimientos de entrada y salida de la cadena raíz y la compresión de estado (bloques de transacción), examinamos todos los métodos de salida y entrada a la cadena raíz, y también investigamos las estructuras de datos básicas: transacciones y bloques.

Usando la cadena lateral basada en la red Ethereum, puede acelerar significativamente las transacciones. Opporty recibió hasta 300,000 transacciones por segundo en un solo operador. Esto es mucho más de lo que pueden proporcionar los sistemas de pago actuales.

A pesar de algunos problemas de disponibilidad de datos, el operador proporciona un alto nivel de estabilidad de blockchain y permite realizar transacciones comerciales internacionales efectivas.

Plasma Cash trae un gran aumento en la escalabilidad. Por lo tanto, Opporty usa Plasma como parte de su protocolo PoE.

Enlaces utiles


  1. Papel blanco plasma
  2. Git Hub
  3. Descripción de casos de uso y arquitectura
  4. Papel de red de rayos

Source: https://habr.com/ru/post/457518/


All Articles