Disputas de Blockchain P2P


La red Ethereum, ampliamente conocida en un círculo estrecho de desarrolladores de blockchain, ya se ha establecido como una plataforma conveniente y estable para desarrollar contratos inteligentes. Intentamos que los contratos inteligentes estén disponibles para usuarios no preparados ofreciendo contratos simples pero prácticamente útiles. Recientemente desarrollamos un contrato inteligente Bet Me disputa. El contrato se basa en una apuesta (disputa) entre dos oponentes. Refuerzan la justicia propia con una tasa de dinero. El perdedor pierde dinero y el ganador se lleva todo. Te contaré más sobre esto en este artículo.


¿Por qué está blockchain aquí?


Para empezar, la pregunta que rara vez se hace a los autores de artículos sobre blockchain es: ¿se necesita blockchain en esta situación? ¿Qué tareas son difíciles de resolver con un acuerdo oral o un contrato legal, pero simplemente con una cadena de bloques?


Si dos personas discutieron verbalmente, esto a menudo se traduce en un nuevo juicio. "No quise decir eso", "Las circunstancias externas influyeron en el resultado, de lo contrario hubiera estado en lo cierto", "Sí, no discutí seriamente contigo, pero lo pensaste para ti mismo" y otras posibles excusas hacen que un argumento oral sea la gran cantidad de personas conocidas tasas bastante bajas. Con apuestas serias y un conocido relativamente distante, es más prometedor concluir un acuerdo por escrito y escribir en detalle la esencia de la disputa, las apuestas, los criterios de decisión y cualquier otra condición que las partes consideren importante.


Este enfoque tiene varias desventajas.


  • En la mayoría de los casos, es necesario atraer a un abogado, o incluso a dos, uno de cada lado, de lo contrario, puede olvidar un punto importante, y esto conducirá a pérdidas financieras.
  • A menudo, solo las obligaciones de las partes se prescriben en el contrato, pero no la responsabilidad por el incumplimiento de estas obligaciones. Como resultado, resulta demasiado fácil para un lado no pagar, y para el otro es extremadamente difícil y costoso obtener su dinero a través de los tribunales.
  • O puede ser que ambas partes insistan en su inocencia, e incluso acudir a los tribunales no garantiza que el ganador obtenga el dinero.
  • Puede resultar que el lado perdedor simplemente no tenga dinero, e incluso una decisión judicial no lo obligará a pagar sus deudas, a pesar de todas las obligaciones.

La cadena de bloques (y la red Ethereum en particular) le permite trabajar con dinero (llamaremos dinero ether; esto no es del todo correcto, pero es conveniente y refleja suficientemente el verdadero estado de las cosas, ya que ether es bastante fácil de cambiar por dinero fiduciario, y viceversa). Al mismo tiempo, en Ethereum, puede reducir los acuerdos a un conjunto de reglas específicas, simplemente no es posible no cumplirlas. Por lo tanto, nuestro contrato inteligente acepta dinero de cada lado y lo bloquea hasta que ocurran eventos específicos. Un conjunto de reglas de programa predefinidas permitirá al ganador retirar dinero. Esto es justo lo que necesitas.


Implementación


Un conjunto de reglas que rigen una disputa se puede implementar de varias maneras. A continuación, hablaremos sobre lo que hicimos para los usuarios de la plataforma Smartz.


La disputa involucra a dos partes. El que crea la copia del contrato en la red Ethereum se llama propietario del contrato (Propietario), y su oponente se llama oponente (Oponente). El propietario del contrato establece una declaración textual que considera verdadera. El oponente está apostando a que la declaración es falsa. La decisión sobre el resultado de la disputa la toma un árbitro independiente (árbitro), cuya candidatura es aprobada tanto por el propietario como por el oponente. El árbitro recibe una comisión en forma de porcentaje del monto de la disputa.


El trabajo del contrato se divide en varias etapas sucesivas.


  1. Las negociaciones El propietario y el oponente, incluso antes de la creación del contrato, pueden negociar de cualquier manera conveniente. Habiendo decidido conjuntamente quién será el árbitro, envían al candidato una invitación para juzgar su disputa. Al recibir la invitación, el árbitro verá todas las condiciones y el Estado correspondiente. Más sobre esto a continuación, pero por ahora es importante entender que el futuro árbitro debe transferir este número al contrato para mostrar en qué condiciones está listo para juzgar a los debatientes. Si el propietario ha establecido un monto de depósito de seguridad distinto de cero (ArbiterPenaltyAmount), entonces, de conformidad con los términos, el árbitro debe transferir la cantidad indicada de tiempo aire al contrato, después de lo cual se bloquea hasta que el árbitro decida los debatientes o hasta la fecha límite para la solución de la disputa. En el último caso, el árbitro pierde la oportunidad de retirar el depósito de seguridad, y este monto se distribuye de manera uniforme entre las partes en la disputa.
  2. Inicializacion . El propietario del contrato crea una instancia del contrato y establece sus parámetros: sujeto de disputa; la fecha en la cual el árbitro debe decidir (Fecha límite); porcentaje de comisión de arbitraje (número fraccionario ≥ 0 y <100); el monto de la fianza (puede ser cero), que el árbitro debe hacer como garantía de que se compromete a decidir la disputa en la redacción existente en el momento adecuado. El propietario también establece la dirección de Ethereum del árbitro en quien confía. Solo el propietario de esta dirección podrá convertirse en árbitro más adelante.
  3. Tasa de propietario Después de establecer, el titular del contrato hace una apuesta. Para hacer esto, envía cualquier cantidad de éter al contrato. Esta cantidad es la tasa, está bloqueada en la dirección del contrato.
  4. El consentimiento del árbitro . La oferta del propietario corrige los términos de la disputa. Ahora el árbitro ve los términos completos de la transacción: la redacción de la disputa, el tiempo antes de que deba tomarse una decisión y, lo más importante, puede comprender cuánto éter recibirá como recompensa. Si el árbitro está contento con todo, confirma su participación y al mismo tiempo transfiere el depósito del seguro.
  5. Busca un oponente . Después del consentimiento del árbitro, comienza la búsqueda del oponente. El propietario establece la dirección del oponente por adelantado, si está listo para discutir solo con alguien específico, o deja la dirección vacía, y luego el propietario de cualquier dirección en la red (excepto el árbitro y el propietario) puede convertirse en el oponente. El oponente confirma la participación en la disputa llamando a un método separado del contrato, al cual transmite el número de versión actual de los datos y la transmisión, tanto como el propietario haya establecido. A partir de este momento, la apuesta se considera concluida. Ahora el contrato está esperando la decisión del árbitro o la fecha límite.
  6. El resultado de la disputa . El árbitro puede juzgar la disputa de tres maneras.
    - Reconocer la afirmación como verdadera. En este caso, el propietario del contrato puede retirar la cantidad total de éter, excepto la comisión del árbitro y el depósito de seguridad (si hubiera uno): el árbitro retira el dinero y el oponente no obtiene nada.
    - Reconocer el enunciado como falso. En este caso, el árbitro puede retirar el éter por el monto de la comisión adeudada a él y el monto del compromiso. El oponente toma el resto, pero el dueño no recibe nada.
    - Declarar la disputa insoluble. Por ejemplo, el propietario creó una disputa con la declaración "El partido de fútbol entre los equipos A y B, programado para el próximo domingo, terminará con un puntaje de 2: 1 a favor de A". Si se cancela el partido, el árbitro no resolverá la disputa, pero debería poder recoger su promesa, porque el problema no surgió por su culpa. En este caso, cada una de las partes puede solicitar la transferencia de aire por el monto de su propia oferta desde la dirección del contrato a su billetera.
  7. Retirar fondos . Cuando el árbitro ha tomado una decisión o la fecha límite ha llegado, cada una de las partes puede solicitar una conclusión al aire. Cuánto éter se generará, el contrato lo calculará, centrándose en los resultados de la disputa.
  8. Destrucción del contrato . El propietario puede enviar un comando de autodestrucción al contrato. Esto puede hacerse antes de la conclusión de la transacción (si no se encontró al árbitro) o después de su finalización (si todas las partes retiraron los fondos que se les deben). Tal oportunidad será útil si, de manera mágica, se recibió más aire del recibido en la dirección del contrato. La probabilidad de tal evento es muy baja, pero aún en Ethereum es imposible bloquear por completo la transferencia de la transmisión a la dirección de un contrato arbitrario, y arrojar dinero congelado es una tontería.

Ahora un poco sobre por qué se necesita el número de versión del estado. Este es el número que aumenta con cada cambio en las condiciones significativas de la disputa, como la redacción de la disputa, el tamaño de las comisiones o multas del árbitro. Cuando alguien acepta los términos de la disputa, él 1) ve el estado actual de los datos; 2) envía una llamada al método de contrato, que registra la aceptación de los términos. Si entre estos dos eventos una de las partes (muy probablemente, el propietario) cambia el parámetro del contrato, usted estará de acuerdo con la otra versión de los datos. Por ejemplo, un candidato a árbitro ingresa a la interfaz del contrato en smartz.io y ve que se le ofrece juzgar una disputa sobre 10 Ether (hoy es de aproximadamente $ 3,000) por una comisión del 1% (aproximadamente $ 30). El candidato acepta felizmente y envía la transacción de confirmación a la red. El propietario deshonesto ve en el grupo minero la transacción bruta del árbitro y envía la suya: cambia la remuneración del árbitro en un 0%. Un estafador pone el precio del gas por encima del promedio y, con cierta probabilidad, los mineros pueden procesar su transacción antes. Tal ataque se llama ataque de ejecución frontal. El número de versión del estado protege contra él. Si la transacción propietario-plaga se procesa antes, el número de versión de los datos en el contrato cambiará. El árbitro en su transacción envió el número de versión de los datos uno menos. Por lo tanto, el contrato se negará a completar la transacción, se producirá una reversión. El árbitro revisará las nuevas condiciones y se negará a participar o aceptará enviando el número de versión actual de los datos.


Cuando desarrolle un contrato de ether, debe pensar mucho en los malos escenarios. ¿Qué pasará si el propietario del contrato decide privar al árbitro? ¿Y si el árbitro resultara ser deshonesto? ¿Qué pasa si el oponente es en realidad un hacker? ¿O están los tres ansiosos de engañarse mutuamente, porque lo que está en juego en la disputa es lo suficientemente alto? Además, es necesario tener en cuenta cualquier posible violación del curso normal de la disputa, cuando la transmisión se bloqueará en el contrato e incluso el propietario no tendrá acceso a ella. Por ejemplo, la opción de declarar la disputa insoluble surgió ya durante la implementación. Por la misma razón, la secuencia de etapas de la disputa es la siguiente: tasa del propietario -> elección del árbitro -> tasa del oponente. Puede suceder que el oponente no confirme su participación, y el tiempo límite se establece en el futuro. Para no convertirse en un inversor a largo plazo, el árbitro puede negarse a participar, pero solo hasta que el oponente haya hecho una apuesta. Y hay muchos matices en el contrato. La buena noticia es que esto debe programarse una vez y usarse. Si la disputa se formalizara como un contrato en papel, en el caso de tales situaciones fronterizas, muchas personas tendrían que examinar cada elemento una y otra vez y acordar entre ellos cómo interpretarlo. La cadena de bloques le permite corregir las condiciones, como en el contrato, pero asignar la interpretación de las condiciones a la máquina virtual y siempre tener un único resultado de su ejecución.


No se puede ignorar el problema de un árbitro interesado. En nuestro contrato, el árbitro toma la decisión solo. Para situaciones simples, esto es suficiente, pero a veces el riesgo de interés personal del árbitro es inaceptable. Una salida es introducir en la lógica del contrato la capacidad de agregar varios árbitros y tomar una decisión mediante votación. Esta es una lógica bastante complicada, especialmente si desea que sea universal para todas las disputas posibles y sus participantes. Sin embargo, la buena noticia es que toda la lógica del arbitraje colectivo complejo puede trasladarse a un contrato inteligente separado. La dirección del contrato que el propietario de la disputa registrará como árbitro. Desde el punto de vista de la interfaz, dicho contrato debería poder invocar varios métodos del contrato de disputa: consentimiento para juzgar la disputa, rechazo de dicho consentimiento, tres versiones de la decisión y un método de transmisión. Dentro del contrato de arbitraje, se puede usar la lógica de decisión de la mayoría de los árbitros, de forma similar a como se hace en el contrato de Multisignature Wallet, también disponible en Smartz.io como constructor.


Para parte de las disputas, es posible reemplazar el grupo de árbitros con un contrato utilizando uno o más oráculos. O invente otra forma, por ejemplo, convertir el argumento en ruleta con una solución aleatoria. Y todo esto, sin cambiar el código del contrato de la disputa y sin complicar la lógica de su trabajo.


Prueba


Quiero decir algunas palabras sobre las pruebas. Todos saben que la automatización de pruebas es buena. Muchos realmente escriben pruebas para su código. Algunas personas utilizan el enfoque TDD en el desarrollo: el largo y conocido Test Driven Development. La diferencia clave entre TDD y las pruebas simples es que las pruebas se escriben antes que el código. Esto le permite ver el código del contrato desde el exterior, sentir los posibles problemas y resolverlos con anticipación. Además, TDD, cuando se usa correctamente, le permite cambiar significativamente la lógica del trabajo si es necesario de repente. El uso adecuado viene con experiencia. TDD no es una bala de plata, como podría pensar, leyendo numerosos materiales sobre este tema. Al mismo tiempo, es preocupante que las guías de desarrollo en Truffle y Node.js no demuestren el uso de TDD para el desarrollo de Solidity. Los desarrolladores novatos adquieren malos hábitos y terminan sufriendo mucho.


TDD implica que hay muchas pruebas en el proyecto. Por ejemplo, el código del contrato de disputa tiene 325 líneas de largo y el código de prueba para este contrato tiene 2144 líneas de largo. En algún momento, las pruebas se hicieron lo suficientemente grandes como para que la prueba de trufa tomara más de un minuto. El ciclo de desarrollo en TDD implica pruebas frecuentes después de cambios menores en el código. Para que el desarrollo no se convirtiera en un tormento, tuve que enseñarle a Truffle a ejecutar solo una parte de las pruebas que coinciden con la expresión regular transmitida.


Debajo del capó, Truffle usa el marco Mocha para las pruebas. Mocha puede filtrar el inicio de las pruebas por intervalos regulares, pero Truffle no puede pasar el parámetro --grep correspondiente desde la línea de comandos fuera de la caja. Aprovechando el hecho de que la configuración de Truffle es un código JavaScript normal, ingresé un análisis de los argumentos de la línea de comandos y la formación de parámetros para Mocha. La configuración, que obtuve como resultado, está disponible en el proyecto GitHub. La implementación no es demasiado bonita, pero funciona y ahorra mucho tiempo.


Resumen


El contrato de disputa se concibió como una funcionalidad muy simple, pero gracias a TDD y al análisis de posibles vectores de ataque, se convirtió en una implementación de restricciones ligeramente más rica. Las deficiencias obvias del contrato están relacionadas con la única decisión del árbitro, sin embargo, pueden eliminarse sin modificar el código del contrato de disputa si el sistema de votación de varios árbitros se implementa en un contrato inteligente separado. El uso de oráculos para disputas en las que esto es posible se realiza de la misma manera.


El contrato de disputa de BetMe se puede probar y ejecutar utilizando una plantilla predefinida en la plataforma Smartz . Esto requerirá una extensión Metamask para el navegador de escritorio o Trust Wallet para dispositivos móviles. Además, el código fuente del contrato en sí está publicado en GitHub.


Vale la pena reconocer que hoy en día el uso de tecnologías blockchain se reduce principalmente a las criptomonedas y al problema de los tokens para las ICO. Las organizaciones autónomas descentralizadas (DAO) aún no se han convertido en realidad. Pero si imagina cómo se desarrollarán aún más los sistemas de contratos de disputas, puede imaginar una lista de árbitros con una calificación, por ejemplo, basada en el Registro de Token Curated. Después de que se completen las disputas, sus participantes podrían votar a favor o en contra de los árbitros con los que trataron, cambiando su posición en el ranking.


Por un lado, el contrato de disputa BetMe es un elemento autosuficiente prácticamente aplicable. Pero, por otro lado, bien puede convertirse en uno de los ladrillos a partir del cual se formará el ecosistema de las organizaciones descentralizadas.


Enlaces


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


All Articles