NXTER.ORG

Programando en la Cripto-Plataforma Nxt #5: Transacciones en la Blockchain de Nxt

Programando para Cripto-Plataforma Nxt #5: Transacciones en la Blockchain de Nxt

Blockchain de Nxt

La blockchain de Nxt es el corazón de Nxt. Todas las transacciones realizadas quedan registradas en la blockchain. El termino blockchain se refiere a una base de datos descentralizada que se guarda en tu ordenador. Para evitar el spam, por cada transacción tienes que pagar una tarifa en el token nativo, en nuestro caso es NXT ya que estamos usando su blockchain. En artículos anteriores he mostrado cómo configurar tu software Nxt así como a visualizar datos. Esta vez, escribiremos datos en la blockchain, empezando con un ejemplo simple. A lo largo del artículo quiero centrarme en las herramientas que puedes usar mientras creamos transacciones en Nxt.

Enviar Nxt

En lo que al código se refiere, crear una transacción en Nxt es muy similar a leer datos de blockchain. Hay algunos temas que tenemos que tratar antes de crear nuestra primera transacción. Para crear una transacción, primero necesitamos tener una cuenta Nxt y algunos NXT, a fin de pagar las cuotas de la blockchain. Por lo tanto, vamos a iniciar una sesión en Nxt y crearemos nuestra primera cuenta.

Crear una cuenta en Nxt

Para tener una cuenta Nxt que cuente con una gran seguridad, necesitas una contraseña fuerte. Trabajando con criptomonedas usamos el término passphrase en lugar de contraseña, esto significa fuerte entropía y, por tanto, debería ser más segura que una contraseña normal. Cuando estás utilizando el cliente oficial de Nxt, puedes utilizar la función implementada de confección de passphrases, la cual te proporcionará una frase de contraseña que contendrá 12 palabras.

Crea tu propia passphrase o frase de contraseña

También puedes crear tu propia frase de contraseña personalizada, pero asegúrate de que contiene suficientes caracteres y entropía. Para generar una frase de contraseña, se recomienda utilizar un software especializado como KeePass, LastPass, Dashlane o herramientas en línea como PasswordsGenerator.net or Fourmilab.ch.

Generador de frase de contraseña Nxt

Al ejecutar Nxt en http://localhost:7876 accederás al cliente. Haciendo clic en el enlace que dice

DON’T HAVE AN ACCOUNT? CLICK HERE TO CREATE ONE!

te llevará al generador de frases de contraseña. Después (o bien con tu propia frase de contraseña generada automáticamente), podrás iniciar la sesión en tu cuenta. Si todavía no tienes NXT, el método es muy rápido si ya posees otras criptomonedas como Bitcoin, Litecoin, Ethereum u otros. Puedes intercambiarlas a través Shapeshift o comprar tus monedas en otro intercambio y transferirlos a tu cartera.

En los pasos siguientes, usamos tu frase de contraseña para firmar y difundir transacciones. Tu contraseña también podría considerarse como tu clave privada (private key).

Crear la transacción

Una vez tenemos una passphrase segura, podemos adentrarnos en el código para crear una transacción de envío de NXT (send-NXT-Transaction). Enviamos 1 NXT a un destinatario, el cual se puede ver en el código, así como cambiarlo por otro destinatario. Inserta tu contraseña en el código siguiente y ejecútalo para crear la transacción.

<!DOCTYPE html>
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
    <div class="col-md-12">
        <h2>Outgoing Transaction JSON</h2>
        
    <div class="well" style="word-wrap:break-word;" id="transactionJSON"></div>
    </div>
  <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  <!-- Latest compiled and minified JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
  <script>
  
  $.post('http://localhost:7876/nxt', {"requestType": "sendMoney", "recipient": "NXT-5RB8-KJD3-BT3B-E2QWW", "amountNQT": "100000000", "secretPhrase": "YourPassphrase", "feeNQT": "0", "deadline": "800", "broadcast": false}, function(request) {
  
        var response = JSON.parse(request);
        $("#transactionJSON").html(JSON.stringify( response , null, 4));
  
      });
      
  </script>
</body>
</html>

Este script está generando una transacción sendMoney. Como puedes apreciar, hemos cambiado la función utilizada en los artículos anteriores $.getJSON por $.post. Cuando creamos las transacciones es necesario cambiar al formato POST en lugar de las solicitudes GET como con las funciones anteriores. Para hacer referencia a los detalles de la API, echa un vistazo a http://localhost:7876/test?requestType=sendMoney.

La salida que se ve en la página contiene información variada, la variable feeNQT se ha rellenado con la información correcta y puedes comprobar el coste de la transacción que has creado. Verás toda la transacción JSON que has insertado en formato JSON y recibirás la transacción transactionBytes. La transacciónBytes incorpora toda la información de la transacción que tienes en la transacciónJSON.

La transacción creada anteriormente todavía no se transmitirá a la red, porque establecemos “broadcast”: false en nuestro objeto. Al establecer esta función en true, la transacción será transmitida y te costará 1 NXT. Como puedes ver, no necesitamos muchas variables para crear nuestra primera transacción.

La receta para una transacción es:

requestType sendMoney
recipient Puedes usar el fotmato RS, por ejemplo, NXT-XXX-XXX-XXX-XXXX o el formato de cuenta numérico
amountNQT La cantidad que deseas enviar debe ser calculada en NQT, el número más pequeño de NXT (1 NXT / 10⁸ = 1 NQT)
secretPhrase Tu frase de contraseña secreta
feeNQT 0 si deseas que el servidor calcule la mínima tarifa de transacción para ti deadline Medido en minutos, cuando expira la transacción.
broadcast:false no emitirá y sólo creará la transacción. Establecer a true para que la transacción se transmita a otros pares y te sea aplicada la tarifa en NXT

Broadcast transaction

Ahora que sabemos cómo crear una transacción sendMoney que todavía no se ha difundido, podemos usar un script similar al anterior para difundir la transacción. Para hacerlo más comprensible estoy ampliacndo el script anterior con un botón que toma la transacción previamente creada y la transfiere a la red al pulsarlo. Efectivamente, al ejecutar el script, tienes tu primera cartera interactiva Nxt (pequeña, ¡todavía no segura!).

<!DOCTYPE html>
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
    <div class="col-md-12">
        <h2>Outgoing Transaction JSON</h2>
        
    <div class="well" style="word-wrap:break-word;" id="transactionJSON"></div>
    <button class="btn btn-primary" id="submitTransaction">Submit this transaction</button>
   
    <hr>
    <div id="broadcastedTransaction"></div>
    </div>
  <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  <!-- Latest compiled and minified JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
  <script>
  
  $.post('http://localhost:7876/nxt', {"requestType": "sendMoney", "recipient": "NXT-5RB8-KJD3-BT3B-E2QWW", "amountNQT": "100000000", "secretPhrase": "YourPassphrase", "feeNQT": "0", "deadline": "800", "broadcast": false}, function(request) {
  
        var response = JSON.parse(request);
        $("#transactionJSON").html(JSON.stringify( response , null, 4));
        $("#submitTransaction").on("click", function() {
          $.post('http://localhost:7876/nxt', {"requestType": "broadcastTransaction", "transactionBytes": response.transactionBytes}, function(broadcast) {
            var broadcastResponse = JSON.parse(broadcast);
            $("#broadcastedTransaction").html(JSON.stringify( broadcastResponse , null, 4));
          }); 
        });
      });
  </script>
</body>
</html>

Cuando cargues el sitio, estarás cargando directamente la transacción aún no difundida. Como la función correspondiente a pulsar en el botón esta anidada dentro de la primera llamada, puedes acceder a los datos de la transacción no emitida. Para emitir la transacción usamos la siguiente receta:

requestType broadcastTransaction

transactionBytes la transactionBytes que hemos creado con la función mencionada anteriormente.

Con estas pocas líneas de código podemos crear una transacción y transmitirla. Sin embargo, todavía estamos definiendo todas las variables directamente dentro del código. En los próximos artículos voy a mostrar cómo agregar mensajes cifrados a una transacción y cómo obtener estos datos a partir de una entrada de usuario que tienes en la página. Profundizaremos en las transacciones por fases y en la poda de las transacciones.

Ver también: http://test.nxter.org/developers

Más artículos de esta serie:

Programando para Cripto-Plataforma Nxt #1: Configuración
Programando para Cripto-Plataforma Nxt #2: Primeras etapas
Programando para Cripto-Plataforma Nxt #3: Output desde el Intercambios de Activos
Programando para Cripto-Plataforma Nxt #4: Datos históricos de los activos

por Tosch

Programando en la Cripto-Plataforma Nxt #4: Datos históricos de los activos

Programando en la blockchain de Nxt #4: Datos históricos de los activos

En el tema anterior, te mostré cómo recuperar los datos básicos de los activos desde el Asset Exchange de Nxt.

En este artículo quiero tratar el tema de cómo recibir el histórico de las operaciones. La llamada a la API que usamos aquí es “getTrades”

Histórico de las operaciones

Las operaciones históricas pueden ser sobre cualquier cuenta o activo. Continuamos con el ejemplo anterior y vamos a obtener las últimas operaciones del activo SuperNET.

Una vez más, vamos a utilizar los parámetros firstIndex y lastIndex para recuperar solo las últimas 10 entradas. Una vez más, vamos a utilizar los parámetros firstIndex y lastIndex para recuperar solo las últimas 10 entradas.

Si desea obtener más operaciones, simplemente cambia lastIndex a un número más alto o borre completamente tanto firstIndex como lastIndex completely.

Si eliminas firstIndex y lastIndex es posible que obtenga un número limitado de entradas, lo que puede configurarse en tu archivo de configuración de Nxt. Echa un vistazo a la propiedad nxt.maxAPIRecords = 100 y ajústala a tus necesidades (sólo cuando estás trabajando sin una contraseña de administrador).

Ahora, volvamos de nuevo al código.

<!DOCTYPE html>
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
  <div class="col-md-12">
    <h2>Trade History</h2>
    <table class="table table-striped">
      <thead>
        <tr>
          <th>Date</th>
          <th>Type</th>
          <th>Quantity</th>
          <th>Price</th>
          <th>Total</th>
          <th>Buyer</th>
          <th>Seller</th>
        </tr>
      </thead>
      <tbody id="tradeHistory">
      
      </tbody>
    </table>
  </div>
  <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  <!-- Latest compiled and minified JavaScript -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
  <script>
  
  $.getJSON('http://localhost:7876/nxt', {"requestType": "getTrades", "asset": "12071612744977229797", "firstIndex": 0, "lastIndex": 9, "includeAssetInfo": "true"}, function(request) {
        
    var trades = request.trades;
    var rows;
    var nxtTime = 1385294400;
    $.each(trades, function(key, data) {
      var decimals = data.decimals;
      var NQT_QNT = 8 - decimals;
      var quantityQNT = data.quantityQNT / Math.pow(10, decimals);
      var priceNQT = data.priceNQT / Math.pow(10, NQT_QNT);
      var total = data.quantityQNT * data.priceNQT / Math.pow(10,8);
      var NxtTimestamp = (+data.timestamp + +nxtTime) * 1000;
      var d = new Date(NxtTimestamp);
      rows += '<tr>';
        rows += '<td>'+d.toDateString()+'</td>';
        rows += '<td>'+data.tradeType+'</td>';
        rows += '<td>'+quantityQNT+'</td>';
        rows += '<td>'+priceNQT+'</td>';
        rows += '<td>'+total+'</td>';
        rows += '<td>'+data.buyerRS+'</td>';
        rows += '<td>'+data.sellerRS+'</td>';
      rows += '</tr>';
    });
    $("#tradeHistory").html(rows);
    
  });
      
  </script>
</body>
</html>

Para la solicitud de la API, como ya se ha indicado anteriormente, hemos limitado la respuesta a 10 entradas, mediante el establecimiento correspondiente de firstIndex y lastIndex. Además, la función includeAssetInfo, establecida como verdadera, mostrará el nombre y el decimal del activo. Esto, aparte de resultar de gran utilidad, hará que la llamada sea un poco más lenta, especialmente cuando estamos visualizando más de un activo.

En lugar de incluir includeAssetInfo podríamos hacer una llamada getAsset para recibir esos parámetros (podría ser recomendable cuando se está visualizando un activo), pero cuando estás mirando las últimas operaciones de una cuenta en lugar de un activo, esto puede ahorrar mucho tiempo y trabajo.

Los cálculos más importantes a mencionar para este script son: la marca de tiempo de Nxt, la cantidad y el precio. Todo se calcula como he explicado anteriormente.

Marca de tiempo (timestamp) de Nxt

Nxt tiene su propio timestamp. Nxt fue lanzado el 24 de Noviembre de 2013, a las 12:00h a.m. En Nxt este sería el timestamp 0. En Javascript sería el 1385294400 (puesto que Javascript empezó el 1 de Enero de 1970, a las 00:00:00), pero puesto JavaScript usa milisegundos, tenemos que multiplicarlo por 1000 para obtener el resultado. Así que al timestamp que nos propodrione Nxt debemos sumarle 1385294400 y añadir los milisegundos para obtener el timestamp en JavaScript.

El análisis de los datos históricos te proporcionará mucha información sobre la frecuencia de las operaciones y cuántas cuentas han estado negociando un activo. Cuanto más cuentas estén involucradas en el comercio, más extendido está el activo entre los compradores y vendedores, lo que generalmente es una buena señal. Por supuesto, tienes que ser consciente de que no sabes el origen de las cuentas. Es posible que una persona cree varias cuentas y haga múltiples transacciones con cada una de ellas. El activo parece tener más volumen del que realmente tiene, lo que parece beneficioso para el propietario del activo. Por otra parte, la gente podría crear varias cuentas para rastrear diferentes tipos de posesiones. En muchos casos, tiene sentido que un usuario tenga más de una cuenta.

El script anterior te mostrará una tabla como la que se muestra a continuación:

programming-nxt-4-1

Información de la cuenta

Como ya sabes, la blockchain es totalmente transparente; puedes ver cualquier transacción de la red y todas las posesiones de una cuenta en concreto. También te permite escribir mensajes cifrados, que no pueden ser leídos por nadie, excepto por aquel que tenga la contraseña del remitente o del destinatario.

El siguiente paso es descubrir cómo crear una interfaz agradable para ver las cuentas. Todos los pasos para conseguirlo se explican aquí.

La llamada a la API necesaria para obtener información de la cuenta es getAccount. También puedes utilizar getAccountAssets para monitorizar las tenencias de los activos, pero getAccount te mostrará todas las posesiones de una cuenta.

Una sugerencia: como en la API de getTrades, puedes decidir incluir más información con includeLessors, includeAssets, includeCurrencies or includeEffectiveBalance.

¡Disfrute programando con Nxt! En el siguiente artículo vamos a explorar la creación de transacciones y más detalles sobre la blockchain. Si tienes alguna pregunta, no dudes en ponerte en contacto conmigo a través del correo electrónico o de mi cuenta de Nxtforum.

Lea el siguiente artículo de esta serie>

Visite también: http://test.nxter.org/developers

Más artículos de esta serie:

Programando para Cripto-Plataforma Nxt #1: Configuración
Programando para Cripto-Plataforma Nxt #2: Primeras etapas
Programando para Cripto-Plataforma Nxt #3: Output desde el Intercambios de Activos

Programando en la Cripto-Plataforma Nxt #3 : Output desde el Intercambio de Activos

Programando en la Cripto-Plataforma Nxt #3: Output desde el Intercambio de Activos

La estrella de las Blockchains

Bienvenido al tercer artículo de programación con Nxt. En los artículos previos he mostrado cómo ajustar tu archivo de configuración Nxt para empezar a desarrollar fácilmente con JavaScript y cómo obtener la primera salida de datos de la blockchain. En este artículo, me gustaría continuar con una de las herramientas más utilizadas en Nxt: el Asset Exchange.

¿Qué es el Asset Exchange o Intercambio de Activos?

El Asset Exchange es un mercado de activos basado en la tecnología blockchain. Todo el mundo puede crear sus propios tokens en la blockchain. El activo puede representar cualquier cosa, ya se trate de servicios financieros, una campaña de crowdfunding, soporte para un sitio web, membresías, commodities o cualquier otra cosa que te puedas imaginar.

La ventaja de usar un token para un activo en la cadena bloques de Nxt es que directamente consigues una audiencia global, ya que ni Internet ni las monedas digitales, tales como Nxt o Bitcoin, no conocen fronteras. Otro beneficio que me gustaría destacar es que nadie necesita una cuenta bancaria real; una vez tienes tu primera moneda virtual es muy fácil moverse de un tipo a otro, y puesto que la tecnología blockchain es accesible para todos, no hay ninguna dificultad para moverla de una persona a otra. (Aun así, deberías informarte sobre tu jurisdicción local para asegurarte de que la creación de un activo está permitida.)

Cómo recuperar los primeros datos de Activos

Para obtener tus primeros datos, primero hemos de elegir un activo. Puedes ver una lista de todos los activos existentes en la red Nxt aquí:Mynxt.info/ lista de activos.
Una vez has elegido un activo, puedes ver el identificador (ID) del activo en la esquina superior izquierda. Necesitaremos el ID para obtener los datos de un activo (Asset). En este ejemplo, he escogido el activo SuperNET ya que se comercializa con frecuencia y tiene muchos datos históricos que podemos ver.

Recuerda que necesitas tener en marcha Nxt en tu sistema para continuar con el resto de este tutorial.

Primero, veamos los metadatos de un asset. El siguiente scrypt de comandos te proporcionará la salida de la configuración de activos original. Como siempre, te recomiendo la página http://localhost:7876/test cuando busques las llamadas de las API. En esta página puedes ver qué llamadas son para recibir datos (GET) o enviar datos (POST) a la blockchain. Empezaremos con las peticiones GET y la llamada getAsset.

Puedes utilizar esta scrypt para mostrar la información de los activos en tu página web, para una descripción general de los activos que se han creado a corto o largo plazo o sólo cómo lista personal de activos y sus funciones.

<!DOCTYPE html>
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
  <h2>Asset Data</h2>
  <table class="table table-striped">
    <thead>
      <tr>
        <th>Key</th>
        <th>Data</th>
      </tr>
    </thead>
    <tbody id="result">
      
    </tbody>
  </table>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

  <script>
      $.getJSON('http://localhost:7876/nxt', {"requestType": "getAsset", "asset": "12071612744977229797", "includeCounts": "true"}, function(request) {
        var rows;
        $.each(request, function(key, data) {
          rows += '<tr>';
          rows += '<td>'+key+'</td>';
          rows += '<td>'+data+'</td>';
          rows += '</tr>';
        });
        $("#result").html(rows);
      });
  </script>
</body>
</html>

El código anterior mostrará una tabla en su página HTML con la siguiente información

programming-nxt-3-1

Llegados este punto, quiero dedicar un poco de tiempo para enseñarte algunas abreviaturas en Nxt:

Verás dos variables “initialQuantityQNT” y “quantityQNT”. QNT significa “Cantidad“, la cantidad inicial es designada por el creador del activo. Como algunos de los activos pueden ser eliminados, el “quantityQNT” nos muestra cuántos activos existen en el momento. También necesitamos la variable “decimals”. El activo que estamos viendo tiene 4 decimales, lo que significa que el número de activos mostrados en la tabla necesita dividirse por 10.000 (4 ceros) para obtener el número real. El activo anterior cuenta con una cantidad  de 816.061.0000 activos.

“Account” es la cuenta numérica de Nxt del creador del activo y “accountRS” es el mismo identificador de cuenta en formato Reed-Solomon (RS).

“numberOfTrades”, “numberOfTransfers” y “numberOfAccounts” son calculadas en el momento en que se ejecuta la llamada.

Puede acortar la llamada de la API “getAsset” sin incluir “includeCounts”: “true” en la anterior llamada $ .getJSON, por lo que no recibirás el número de titulares del activo, las transferencias y operaciones, por lo que la llamada a la API será más rápida.

Órdenes de compra y venta

Después de conocer los detalles sobre el activo y obtener los metadatos, nos interesa saber si hay órdenes de compra o de venta para este activo y a qué precio se comercializa actualmente. Los métodos para utilizar los cálculos de cantidades o posiciones decimales de Nxt no siempre son los más óptimos. A veces, en este tutorial, escojo los métodos que son más comprensibles en lugar de los más óptimos. Por lo general, yo recomendaría hacer cálculos con los números originales de la API, porque no tendrás que ocuparte de los decimales y de ahí es de dónde provienen la mayoría de los errores. Las llamadas API que estamos utilizando para esto son: getAskOrders y getBidOrders. Una vez más, necesitamos el ID del activo para obtener las órdenes de compra y de venta del mismo. Además, acortaremos la salida agregando los parámetros firstIndex y lastIndex. Aquí está el código para obtener tanto las órdenes de compra como las de venta para el activo SuperNET:

Ask Orders

 

QuantityPriceTotal

Account

 

Bid Orders

 

QuantityPriceTotal

Account




programming-nxt-3-2

El script anterior se puede usar para visualizar los precios y las ofertas actuales de cualquier activo en tu página web, y para mostrar el libro de órdenes completo. Además, puedes utilizarlo para analizar las tendencias. Puesto que, además, dispones de todas las cuentas correspondientes a las ofertas y las demandas, puedes analizar las ofertas y obtener el número de cuentas que están operando en la plataforma.

Esta vez hemos tenido que hacer más consultas $.getJSON para obtener la información que queremos. Primero, necesitamos los decimales de los activos para hacer el cálculo sobre la cantidad, como mencionamos  en la primera llamada. En segundo lugar, queremos obtener tanto las órdenes de compra como las de venta. Esto necesita una consulta para cada una de las llamadas a la API.

También vemos una nueva variable que necesita una breve explicación. “PriceNQT” es el precio de un Activo por QuantityQNT.

El precio en la API se muestra en priceNQT por QuantityQNT. Entonces, ¿qué es NQT y cuál es la diferencia con QNT? NQT se refiere a NXTQuant, el número más pequeño que existe en NXT, que es 0,00000001 NXT (8 decimales). También tenemos que tener en cuenta los decimales, que tenemos que multiplicar de nuevo para obtener el precio real por activo. He utilizado la variable var NQTdivider = 8 – decimales; Para obtener el número por el que necesitamos dividir la cantidad para, de este modo, obtener el precio actual en NXT por cada Quantity.

Espero que hayas disfrutado con esta tercera entrega de “Programación en la Cripto-Plataforma Nxt”. En el próximo artículo, hablaré sobre los datos históricos y la información de la cuenta. Si tienes alguna pregunta, no dudes en ponerte en contacto conmigo a través de correo electrónico o de mi cuenta de NxtForum.

Lea el siguiente artículo de esta serie>

Visite también: http://test.nxter.org/developers

Más artículos de la serie:

Programación en la Cripto-Plataforma Nxt #1: Configuración
Programación en la Cripto-Plataforma Nxt # 2: Primeros pasos

Por Tosch

 

Programando en la Cripto-Plataforma Nxt #2

Programando en la Cripto-Plataforma Nxt #2: Primeros pasos

Sobre Nxt

¿Alguna vez has querido participar con tu propio software en el sector financiero sin correr grandes riesgos, contando con un acceso fácil y anónimo al mismo? ¿Alguna vez has intentado acceder a los sistemas monetarios y obtener datos fidedignos de la bolsa mercados o centros de datos en la nube? El software Nxt consiste en una cadena de bloques (Blockchain) entre pares (peer-to-peer) que permite un servicio financiero global, que puedes disfrutar en tu propio servidor u ordenador. No es necesario registro alguno ni ningún tipo de procedimiento burocrático.

¿Qué es la Blockchain de Nxt y qué aporta?

En los sistemas bancarios tradicionales te encuentras con bancos en los que depositas tu “confianza”, que amablemente se ofrecen a administrar tu dinero y tus bienes. Sin embargo, cuando quieres acceder a tu dinero no te dan facilidades. Especialmente, como desarrollador, no hay ninguna posibilidad de que puedas recuperar toda la información sobre tus posesiones ni que puedas acceder a los datos históricos de Wall Street de forma gratuita.

Con el sistema de cadena de bloques peer-to-peer, Nxt ha comenzado a construir un ecosistema centrado en la manipulación segura y transparente de los datos. Puedes iniciar tus propios servicios, crear divisas, crear activos y comercializarlos, beneficiarte de un mercado integrado, una nube de datos y ¡mucho más!

Comencemos

Con las siguientes líneas de código me gustaría enseñar cómo obtener un primer acceso a los datos de Nxt para, posteriormente, mostrar cómo añadir información a la cadena de bloques y obtener datos listos para utilizar en tu página web.

A partir de ese momento, podrás comenzar a construir todo lo que puedas imaginar alrededor de la blockchain, el libro de contabilidad y todas las herramientas de las que dispones.

Si todavía no has instalado Nxt, consulta aquí cómo instalar y configurar Nxt para comenzar a desarrollar.

“Hello World”

En este ejemplo, vamos a optar por la configuración más básica que nos permita mostrar los datos de la blockchain en nuestra página web.

Usaremos JQuery para simplificar la llamada a la API, pero puedes lograr los mismos resultados con otros frameworks o con un poco más de código.

Vamos a crear el primer archivo html, al que llamaremos transaction.html, dónde insertaremos el siguiente código.

<!DOCTYPE html>
<html>
<body>
  <div id="result"></div>
  <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  <script>
      $.getJSON('http://localhost:7876/nxt', {"requestType": "getTransaction", "transaction": "8520011591947303971"}, function(request) 
      {
        $("#result").html(request.attachment.message);
      });
  </script>
</body>
</html>

Nxt tiene una documentación API muy útil a la que se puede accede en http://localhost:7876/test. En este ejemplo estamos utilizando la llamada getTransaction, que también se puede probar en la página de la API.

Al ejecutar el script anterior, deberías recibir la siguiente respuesta en tu navegador:

Hello World Congratulations! You have received the first data from the blockchain.
Pero,¿qué ha pasado aquí?

En primer lugar, hemos utilizado la llamada API “getTransaction” que nos permite tener una visión detallada de la información de cualquier transacción que se encuentra en la blockchain. Echa un vistazo a la consola del navegador para ver toda la información de la transacción.

En el código anterior, hemos accedido al output o salida del mercado de la respuesta JSON que nos dio la API de Nxt. Aquí puedes ver todo el objeto devuelto desde la API.

{
                            "senderPublicKey": "7969c2ec61af9bedd3260c9b2cd4a292ba01ecbc2901a86851fa6c68208b0766",
                            "signature": "d13ad29034e56ae58b7f1eee4979cd6dffff38a7a26094c86103e431faf0bd06084be1e42534efd8e76b8a59c12630b52d851c571a25bc54af9ebdb56ca6df14",
                            "feeNQT": "100000000",
                            "requestProcessingTime": 0,
                            "type": 0,
                            "fullHash": "23bc3ae466293d7690b426173445e5b87423ea798b1d9c2913feda5d0d52a5b6",
                            "version": 1,
                            "phased": false,
                            "ecBlockId": "15499194118663359315",
                            "signatureHash": "9ea43451798a0144bd6cea58cbbba479c24ed7cdc29a4077a9aeb49a063498a7",
                            "attachment": {
                                "version.Message": 1,
                                "messageIsText": true,
                                "message": "Hello World",
                                "version.OrdinaryPayment": 0
                            },
                            "senderRS": "NXT-5RB8-KJD3-BT3B-E2QWW",
                            "subtype": 0,
                            "amountNQT": "10000000000",
                            "sender": "14876164227056393510",
                            "recipientRS": "NXT-P439-YVBD-VUEQ-A3S2T",
                            "recipient": "10124938546868029479",
                            "ecBlockHeight": 614717,
                            "deadline": 1440,
                            "transaction": "8520011591947303971",
                            "timestamp": 67508752,
                            "height": 2147483647
                        }

¿Por qué usar getJSON?

Como hemos estado utilizando getJSON la función Jquery, no necesitamos analizar más el JSON y podemos acceder directamente al JSON que nos devuelve la API de Nxt. Cuando se utiliza una llamada ajax o get method de JQuery, es posible que necesites enviar JSON.parse (request) para acceder al objeto.

La transacción 8520011591947303971que hemos accedido en el código, era una transacción que yo previamente había enviado. Todas las transacciones dentro de Nxt son transparentes y todo el mundo las puede ver. Echa un vistazo a la respuesta JSON de la Api de Nxt y con tu script en la mano ya puedes mostrar toda la información que te interese de cualquier transacción.

Reemplace request.attachment.message (por ejemplo, con request.accountRS) para que se muestre la identificación de la cuenta y continúa para dotar de una vista agradable a la información.

En los siguientes artículos te mostraré cómo enviar los primeros datos a la cadena de bloques, cómo recuperar datos de los Activos, cómo calcular los precios y cómo ver las órdenes abiertas

Alcanzando las estrellas

Nxt te apoya en la creación de un software que te permite el comercio global en una red peer-to-peer dónde cada participante es igual de importante. Comienza a construir cosas impresionantes con Nxt.

Lea el siguiente artículo de la serie:

Más artículos de la serie:

Programando en la Cripto-Plataforma Nxt #1

Visita también: http://test.nxter.org/developers

Cervezas, apuestas y la blockchain de Nxt

Supongamos que tienes un grupo de amigos con los que te reúnes un un bar de deportes para tomar una cerveza, ver eventos deportivos y hacer apuestas. Pues es posible hacer apuestas utilizando la blockchain de Nxt utilizando una sencilla aplicación Python que lo automatice todo.

En mi primer artículo presenté los conceptos básicos de la blockchain. Tal y como vimos, el principal valor de la cadena de bloques es la inmutabilidad de los datos contenidos en las transacciones almacenadas en cada bloque, a partir de los cuales se construye la blockchain.

Hoy quería mostrar como construir una aplicación de apuestas en python de manera sencilla pero funcional. Para esta aplicación es básico que los datos sean inmutables, pero en caso de que sea necesario que una apuesta se pueda cancelar, se puede modificar la app para incluir esta funcionalidad adicional.

Prerrequisitos:
NRS (Software de Referencia Nxt) 1.10.2: https://bitbucket.org/JeanLucPicard/nxt/downloads/Python 3 (o Python 2 con una ligera modificación). Una cerveza o dos (opcional).

Lógica de la aplicación

Un usuario emite una apuesta (transfiere una determinada cantidad de monedas NXT) a la cuenta de apuestas y le añade un adjunto público y sin encriptar. En el adjunto se debería incluir el identificador de la apuesta, dos puntos, y un número indicando su elección en la apuesta correspondiente. Pongamos un ejemplo: el bar de eventos deportivos crea una porra sobre qué equipo saldrá victorioso en un partido de fútbol. Le asigna un Identificador (ID) al partido, por ejemplo “30”.

Las opciones son:
“1” – gana el equipo de casa “2” – gana el equipo visitante. “3” – empatan.

Para apostar que gana el equipo de casa, el jugador debería enviar una transacción con una determinada cantidad de NXT, adjuntando un mensaje público sin encriptar (para que sea auditable) con el siguiente contenido 30:1

Cuando llegue el momento, el gestor de la apuesta ejecuta la app para localizar a los ganadores y realizar los pagos. El gestor puede quedarse una pequeña comisión por el servicio prestado.

Implementación

El servidor Nxt recibe las peticiones en el puerto 7876. Si por defecto lo ejecutas en el mismo equipo en el que ejecutas el código python debes enviar tus peticiones a http://127.0.0.1:7876/nxt

Para nuestra app necesitaremos importar unos pocos módulos y escribir la función para hacer consultas que se usará unas cuantas veces en la ejecución de la app.

import sys, json, re

def sendQuery(Query):
  from urllib import parse, request
  params = parse.urlencode(Query)
  headers = {"Content-type": "application/x-www-form-urlencoded", 
"Accept": "text/plain"}
  req = request.Request("http://127.0.0.1:7876/nxt", 
params.encode('utf-8'))
  response = request.urlopen(req)
  return response.read()
	
myAccount = "NXT-AAAA-BBBB-CCCC-DDDDD"
totalAmount = 0
serviceFee = 0.05
players = []
secretPhrase = "bla bla bla"

La función devuelve una cadena JSON que necesita ser decodificado, con transacciones y adjuntos que necesitan ser analizados. También se inician unas determinadas variables

A continuación debes pedirle a la cuenta con las apuestas que busque en todas las transacciones entrantes.

Esta es la solicitud que puedes enviar al servidor Nxt para ejecutar esto:Query = {‘requestType’: ‘getBlockchainTransactions’,

'account': myAccount, 'type': '0', 'subtype': '0', 'executedOnly': 'true'}

decode JSON and load it to a variable for further processing.

output = sendQuery(Query)
data = json.loads(output.decode('utf-8'))

Puesto que ahora ya contamos con todos los datos, ejecutamos un loop en la tabla para deshacernos de las transacciones que no necesitamos. Por ejemplo, no necesitamos procesar las transacciones salientes, así que continuamos nuestro loop desde el siguiente objeto

for i in data['transactions']:
  txAmount = i['amountNQT']
  txSender = i['senderRS']
  if txSender == myAccount:
      continue
  txRecipient = i['recipientRS']
  if txRecipient != myAccount:
      continue

A continuación extraemos los adjuntos, nos aseguramos de que no están encriptados y quitamos los espacios en blanco

  line = i['attachment']['message']
  lineIsText = i['attachment']['messageIsText']
  if line.strip() != "" and lineIsText == True:
    line = line.strip()

El siguiente paso es hacer concordar el mensaje enviado con la expresión regular. Tiene que satisfacer el formato “Número:Número”, el primer número puede contener hasta 3 dígitos.

    matchLine = re.match(r'(\d{1,3}:\d{1})(.*)', line, re.M|re.I)

Si el mensaje adjunto tiene un formato correcto, continuamos analizando…

La aplicación para las apuestas acepta hasta un máximo de 3 argumentos en la línea de comandos: identificador de juego, el número elegido que ha ganado, y un tercer parámetro opcional entre comillas para mostrar la combinación ganadora en el mensaje con el pago.

Por ejemplo, el anfitrión de la apuesta debe ejecutarlo del siguiente modo:

python3 bet.py 30 1 “El equipo local gana”

La aplicación analizará las transacciones con id 30 y premiará a los jugadores que eligieron ‘1’.
El tercer argumento se podría omitir: python3 bet.py 30 1

A continuación debemos calcular la cantidad de dinero que ha recibido nuestro, haciendo un listado diccionario de jugadores que adivinaron el número correcto, y calculando la suma total de dinero a distribuir una vez que el anfitrión ha recibido su comisión opcional.

    if matchLine:
      if matchLine.group(1).split(':')[0] == sys.argv[1]:
        totalAmount += int(txAmount)
        if matchLine.group(1).split(':')[1] == sys.argv[2]:
          d = {txSender: matchLine.group(1).split(':')[1], 
'amount': txAmount}
          players.append(dict(d))
afterFee = float(totalAmount - totalAmount * serviceFee)

Tenemos ganadores en la lista ‘players’ de los diccionarios, tenemos dinero para distribuir en el apartado ‘afterFee’, ahora dinos los pagos de premios procesados.

sumCorrect = 0
for i in players:
  for key in i:
    if i[key] == sys.argv[2]:
      sumCorrect += float(i['amount'])
for i in players:
  for key in i:
    if i[key] == sys.argv[2]:
      t = float(i['amount']) * (afterFee / sumCorrect)
      if t > afterFee:
        strSendAmount = str(int(afterFee))
      else:
        strSendAmount = str(int(t))
      if len(sys.argv) > 3:
        reply = sys.argv[3]
      else:
        reply = sys.argv[2]
      message = "Payout for correct bet in poll " 
+ sys.argv[1] + "; your reply: " + reply
      Query = {'requestType': 'sendMoney', 'recipient': key, 
      'amountNQT': strSendAmount, 'secretPhrase': secretPhrase, 
      'feeNQT': '100000000', 'deadline': '1440', 'broadcast': 'true', 
'message': message, 'messageIsText': 'true', 'messageIsPrunable': 'true'}
      sendQuery(Query)

No es necesario decir que la app se puede optimizar para procesar errores, cancelar apuestas u, opcionalmente, permitir otros parámetros en los mensajes adjuntos. Los mensajes adjuntos se pueden emitir desde el cliente Nxt (NRS) o desde un monedero online que permita enviar adjuntos

Para realizar transacciones en la blockchain de Nxt necesitas monedas NXT, que puedes adquirir directamente cambiando Bitcoin por Nxt o participando en el proyecto del “Nodo afortunado” ejecutando un nodo público de Nxt (Nxt server).

Para saber como participar en el proyecto del “Nodo afortunado”, por favor visita https://nxtforum.org.

Hay más de un centenar de llamadas API que se pueden solicitar al servidor Nxt. Una lista completa de parámetros obligatorios y opcionales así como ejemplos está disponible en https://nxtwiki.org/wiki/The_Nxt_API.

¡Salud!

blockchain-betting

Lotería en la Blockchain de Nxt programada en Golang

En mi primer artículo hice una introducción teórica de la blockchain, de lo que puede aportar para tu proyecto de software y los conceptos básicos para interactuar con la blockchain de Nxt en PHP.

Hoy voy a presentar un pequeño programa de lotería escrito en Go.

Requisitos previos:
Golang (testado con Go 1.6.2)
NRS 1.10.1 (https://bitbucket.org/JeanLucPicard/nxt/downloads/)

Este programa es completamente funcional y ejecuta un sorteo de lotería todos los domingos [1]. Originalmente fue escrito en PHP, las dos fuentes están disponibles para su descarga desde el Data Cloud de Nxt [2].

Lógica de la aplicación

Los boletos enviados por los usuarios en mensajes adjuntos son el suministro de datos para esta aplicación.

Un jugador de la lotería envía 10 NXT a la cuenta de la lotería adjuntando un mensaje público no encriptado con una secuencia de 5 números, entre el 0 y el 30, separados por comas. El mensaje adjunto tiene que ser público para que las recompensas sean auditables usando la blockchain.

La app hace una llamada al servidor NXT para que le proporcione todas las transacciones desde la cuenta de la lotería, clasificándola y seleccionando únicamente las transacciones válidas para así crear un trozo de mapa (conjunto multidimensional en PHP) de todas las cuentas de los jugadores y de sus cadenas de números.Esto también calcula la suma total, de Nxt, a pagar a los jugadores calculando la suma total de todos los boletos validados.

La app, una vez que ha recibido todos los datos válidos, ejecuta 3 rondas de lotería. Cada una de esas rondas recibe una porción, de la suma total disponible para los pagos, a repartir entre los ganadores. En la ronda de 5, la aplicación encuentra los usuario que han adivinado correctamente los 5 números y envía las recompensas. En la ronda 4, la aplicación hace lo mismo para los usuarios que han adivinado 4 números, el monto restante de los boletos participantes es ahora menor que la del ganador(es) de la ronda 5. Se repite lo mismo para la ronda 3.

Esta es la esencia de como funciona la aplicación.

Un poco más sobre el funcionamiento interno

Para cada una de las tres rondas, la lotería genera secuencias de 5 números y las compara con las cadenas de números de los boletos hasta que encuentra uno o más ganadores. Se puede decir que la lotería “fuerza” encontrar una secuencia ganadora del boleto(s).

Con un número limitado de usuarios esto parece ser la única manera sensata para ejecutar una lotería y no tener que recoger y guardar un premio gordo durante meses y/o años.

Vamos a echar un vistazo a la función que genera la secuencia de los 5 números y devuelve una matriz de ellos a la función de llamada. Esta función se invoca un promedio de cientos de miles de veces para encontrar la secuencia de 5 números en una de las entradas cuando tenemos un número muy limitado de participantes. Se tarda una fracción de segundo. En PHP se necesita un poquito más de tiempo (uno o dos segundos), aunque el rendimiento de PHP 7 es realmente bueno.

func genFive(seed string) [5]int {
   var r [5]int
   seedInt, _ := strconv.Atoi(seed)
   d := false
   for a := offset; a < offset+5; a++ { 
      rand.Seed(int64(seedInt + offset)) 
      var dup [31]int 
      d = false 
      r[0] = rand.Intn(31) 
      r[1] = rand.Intn(31) 
      r[2] = rand.Intn(31) 
      r[3] = rand.Intn(31) 
      r[4] = rand.Intn(31) 
      for _, v := range r { 
         dup[v]++ 
      } 
      for k, _ := range dup { 
         if dup[k] > 1 {
            d = true
         }
      }
      offset = offset + 5
      if d == false {
         return r
      }
   }
   return r
}

Una característica importante de la lotería en la blockchain es que tiene que ser completamente transparente.
Todo el mundo debe poder validar que los resultados de la lotería no han sido alterados. Una solución lógica y simple a esto es generar secuencias de números con una semilla determinista.

El problema con las semillas deterministas es que, si se sabe de antemano, las secuencias de números se puede predecir y , a se podría llegar a hacer trampas en la lotería. Para hacer frente a este problema volvemos de nuevo a la Blockchain de NXT, para encontrar una fuente de semilla con la función getSeed().

func getSeed() (string, string) {
 type BlockchainStatus struct {
    NumberOfBlocks int `json:"numberOfBlocks"`
 }
 var status BlockchainStatus
 if seedBlockOutput, b := 
sendQuery("requestType=getBlockchainStatus", 
true); 
b != false { if err := 
json.Unmarshal([]byte(seedBlockOutput), &status); 
err != nil {
     fmt.Println(err)
   }
  }
 seedBlockHeight := 
strconv.Itoa(status.NumberOfBlocks - 11)

 type BlockId struct {
  Block string `json:"block"`
 }
 var block BlockId
 if seedBlockId, b := 
sendQuery("requestType=getBlockId&height="
+seedBlockHeight, true); b != false {
if err := json.Unmarshal([]byte(seedBlockId), 
&block); err != nil {
         fmt.Println(err)
    }
  }
 seed := block.Block[len(block.Block)-5:]
 return seed, seedBlockHeight
}

La app se ejecuta cada domingo a las 18:00 UTC.

Lo primero que esto hace en la función getSeed() es ir a buscar la identificación del bloque que se generó 10 bloques antes del inicio de la aplicación (como se puede ver en la copia local de la blockchain en el nodo de la lotería) y obtener los últimos 5 dígitos de la ID del bloque como semilla. Debido a la latencia de la red y las reorganizaciones ocasionales de la blockchain (de 1 a 3 bloques) el nodo de la lotería puede que no vea la misma información que los otros nodos. El número 10 para obtener el bloque de la semilla fue escogido por la razón que debemos estar razonablemente seguros que este bloque no será reorganizado.

Puede afirmarse que existe la posibilidad teórica de que pueda predecirse el identificador del bloque. En mi opinión, las posibilidades de que esto suceda son muy bajas, pero dejo a los lectores que lo debatan y decidan por ellos mismos.

Ahora que la App tiene su propia semilla, puede realizar su función de manera que los usuarios no necesiten confiar en el organizador de la lotería.

El código fuente “Go” no incluye la rutina de verificación de los resultados anteriores.
El código fuente “PHP” lo tiene, es totalmente funcional y se puede utilizar para verificar, de manera independiente, todos los resultados anteriores con las semillas deterministas de la blockchain.

Para “Go” yo uso la función de enviar y retornar solicitudes al servidor Nxt.

func sendQuery(Query string, Active bool) 
(output string, b bool) {
   output = ""
   b = false
   if Active == false {
      output = "Function disabled"
      return
   }
   body := strings.NewReader(Query)
   req, err := http.NewRequest("POST", 
"http://127.0.0.1:7876/nxt", body)
   if err != nil {
      output = fmt.Sprintf("%s", err)
      return
   }
   req.Header.Set("Content-Type", 
"application/x-www-form-urlencoded")

   resp, err := http.DefaultClient.Do(req)
   if err != nil {
      output = fmt.Sprintf("%s", err)
      return
   }
   bo, err := ioutil.ReadAll(resp.Body)
   defer resp.Body.Close()
   output = fmt.Sprintf("%s", bo)
   match, _ := 
regexp.MatchString(".*errorDescription.*", 
output)
   if match == true {
      fileHandle, _ := 
os.OpenFile("./error.log", os.O_APPEND, 0666)
      writer := bufio.NewWriter(fileHandle)
      defer fileHandle.Close()
      fmt.Fprintln(writer, output)
      writer.Flush()
      return
   }
   b = true
   return
}

Los resultados son recibidos como una cadena JSON y necesitan estar ordenados con una estructura apropiada.

validPlayers := make([]map[string]string, 0)

lotteryAccount := "NXT-YXC4-RB92-F6MQ-2ZRA6"

type Attachment struct {
   Message       string `json:"message"`
   MessageIsText bool   `json:"messageIsText"`
}

type Transaction struct {
   Timestamp   int        `json:"timestamp"`
   AmountNQT   string     `json:"amountNQT"`
   ID          string     `json:"transaction"`
   SenderRS    string     `json:"senderRS"`
   RecipientRS string     `json:"recipientRS"`
   Attached    Attachment `json:"attachment"`
}

type Response struct {
   Transactions []Transaction 
`json:"transactions"`
}
Query := 
"requestType=getBlockchainTransactions&account=" +
lotteryAccount + 
"&type=0&subtype=0&executedOnly=true"

if v, a := sendQuery(Query, true); a == true {
   var transactions Response
   if err := json.Unmarshal([]byte(v), 
&transactions); err != nil {
      fmt.Println(err)
   }

 p := 0
 for k, _ := range transactions.Transactions {
    // code to check tickets for validity.
    // if transaction satisfies all criteria 
    // add it to the slice of valid tickets.
		
    validPlayers = append(validPlayers, 
make(map[string]string))
    validPlayers[p][txSender] = lotteryNumbers
    p++
			
   }
}

Ahora que “validPlayers” tiene todas las entradas correctas podemos iniciar el juego.

process() recibe un número entero (5, 4, o 3) y otros parámetros, incluyendo validPlayers y ejecuta tres rondas de la lotería. Se hace una llamada a la función getWinners(), que se llama genFive() para generar secuencias de números hasta que se encuentre al menos un ganador. getWinners() devuelve los resultados a process() y este es el encargado de: enviar la recompensa, eliminar el boleto ganador y devolver las entradas restantes a main() para rondas posteriores. Hay una función auxiliar denominada preparePlayers() que recrea validPlayers sin los espacios vacíos liberados por las entradas eliminadas.

Animo a todos los programadores que programen en el blockchain NXT. Es muy sencillo gracias al enlace API de todas sus funcionalidades del núcleo. https://nxtwiki.org/wiki/The_Nxt_API

Mi próxima aplicación será probablemente una aplicación de votación, con registros de votos inmutables y guardados en la blockchain. ¿Cree usted que una aplicación como esta puede resultar útil en el mundo moderno? Por cierto, Nxt tiene incorporado su propio sistema de votación. Es muy fácil olvidar lo que Nxt tiene, porque dispone de muchas características que son accesibles a través de la API, que se encuentra amablemente programada por los desarrolladores del núcleo de Nxt para favorecer su uso. Puedes ‘mínar’ tus primeras monedas NXT para enviar las transacciones al proyecto del nodo de la suerte que se ejecuta en un nodo público, acude a nxtforum.org y encontrarás la manera.
Por favor, dejen sus sugerencias y comentarios.

 


1. Lotería en nxtforum.org.

2. Para acceder al Nxt Data Cloud (Nube de datos de Nxt), descargue e instale el NRS (Nxt Reference Software 1.10.1) y busque la palabra clave lottery. Puedes descargar el código fuente desde cualquier servidor Nxt con las API abierta, por ejemplo:

Go-> http://23.94.134.161:7876/nxt?requestType=downloadTaggedData&transaction=7872865106538381099&retrieve=true PHP: http://23.94.134.161:7876/nxt?requestType=downloadTaggedData&transaction=13031806327722095646&retrieve=true

DE VUELTA AL POST.

Programando en la Blockchain de Nxt por diversión y para obtener ganancias

Las cadenas de bloques o blockchains son útiles para múltiples aplicaciones, permitiendo llegar a una audiencia global y reforzando la infraestructura interna de una compañía. Una blockchain es una base de datos distribuida, dónde una copia de esta cadena de bloques está almacenada en cada uno de los nodos de una red entre pares (red peer-to-peer o p2p). Esta redundancia extrema podría ser considerada ineficiente pero, por favor, déjame que te explique brevemente un poco de teoría sobre las blockchains.

Puesto que cada nodo valida todas las transacciones almacenadas en la blockchain y dado que las transacciones pasadas no pueden ser deshechas ni alteradas como sucede en los tradicionales Sistemas de Gestión de Bases de Datos Relacionales (RDBMS por sus siglas en inglés), esta redundancia convierte a la blockchain en “inmutable”, siendo este uno de los grandes valores de las cadenas de bloques. La inmutabilidad de la información es algo que las bases de datos tradicionales no pueden proporcionar. Puede que necesites, o no, esta inmutabilidad de los datos, así como una una confirmación, sin tener que confiar en terceros, de que los datos no han sido alterados.

En este tutorial presupongo que esto es lo que necesitas.

Una de las cadenas de bloques más versátiles y flexibles es la blockchain de Nxt (https://nxt.org). Cuenta con más de un centenar de llamadas API https://nxtwiki.org/wiki/The_Nxt_API.

En esta ocasión te voy a mostrarlos conceptos básicos para programas en la blockchain de Nxt. Sólo voy a usar dos llamadas API en este tutorial. Dado que existen más de un centenar de llamadas API posibles, las oportunidades para los programadores no tienen límite.

Lógica de aplicación

Un cliente de una compañía o un empleado de una organización sube un archivo a través de un formulario web.

El archivo es renombrado para dotarlo de un nombre único y es almacenado en algún lugar del servidor.

Un año más tarde el cliente / empleado necesita verificar, usando la blockchain de Nxt, que el archivo no ha sido alterado. Por ejemplo, esto puede ser necesario por motivos legales. No tiene porque ser sólamente archivos. A los memorandos internos de la compañía se les puede aplicar un algoritmo hash y ser incorporados a la base de datos, para poder ser verificados en una futura auditoría.

Nxt nos permite enviar y almacenar mensajes arbitrarios (M.A.) en su cadena de bloques.

Cada transacción en la blockchain acarrea una tasa o fee. Si el tamaño de la transacción es grande, podría ser caro. Afortunadamente Nxt tiene un subtipo de M.A. llamado mensaje podable. Estos mensajes son “podados” o eliminados pasados 90 días, lo que los hace más baratos. También sería posible recuperar estos mensajes pasados 90 días a partir de los Nodos de Archivo.

El tamaño máximo de un mensaje arbitrario en la blockchain de Nxt es de aproximadamente 42Kb, el tamaño de un bloque. Un mensaje podable de 1KB cuesta 1 NXT (0,03$). 1KB es suficiente para almacenar el hash de un archivo y este será nuestro coste final para almacenar permanentemente un hash en la inmutable y distribuida cadena de bloques de Nxt.

Tan pronto cómo el cliente sube el archivo yo creo un hash del tipo SHA256 del archivo y lo almaceno este hash en la base de datos del servidor de la organización. Por sencillez yo he elegido SQlite, pero puedes usar Mysql, Postgresql, Oracle. Usaré la extensión Objetos de Datos de PHP (PDO por sus siglas en inglés) para acceder a la base de datos SQlite en PHP.

Cuando no utilizamos la base de datos inmutable (blockchain), el archivo puede ser modificado, almacenarse en la base de datos el nuevo hash del archivo modificado, haciendo difícil demostrar que el archivo era el mismo que en un principio.

La blockchain viene al rescate

Cada mensaje podable se puede recuperar desde los nodos de archivo. Cada registro de la blockchain es inmutable. Puedes estar seguro de que el hash del archivo que subiste hace un año será el mismo cuando lo descargues de la cadena de bloques. Todo lo que necesitas hacer es compararlo con el hash del RBDMS interno de la organización.

Prerrequisitos:

PHP con curl, json y algún tipo de extensión de la base de datos (yo uso sqlite3). Un servidor web es opcional, puedes utilizar php-cli. Java 8 (Oracle o OpenJDK para ejecutar Nxt). Software de Referencia Nxt: https://nxtforum.org/nrs-releases/nrs-v1-10-1/.

Instala el Software de Referencia Nxt (NRS por sus siglas en inglés. Dependiendo del contexto se le llama indistintamente Cliente Nxt o Servidor Nxt) y crea una cuenta. Dótala con unas pocas monedas. Puedes intercambiar Bitcoin por Nxt en un servicio de exchange como https://shapeshift.io o intercámbialas directamente con otros usuarios en https://nxtforum.org. También es posible “minar” algunos NXT gratis como recompensa por tener un nodo: http://test.nxter.org/the-forging-bounty-lottery-campaign-will-pay-5-million-in-rewards-to-forgers-and-nxt-nodes/.

Primero creamos una base de datos sencilla para nuestra aplicación, nada extraordinario, si necesitas almacenar más información puedes añadir más columnas. A mí me gusta utilizar el navegador de bases de datos (DB browser) para SQLite de http://sqlitebrowser.org.

Vamos a crear una base de datos vacía llamada ‘files.db’ y la guardamos en /home/lurker10/phptutorial/files.db

Usando el DB browser para SQLite crea la siguiente tabla:

CREATE TABLE "files" (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`txid` TEXT,
`hash` TEXT,
`uploadtime` TEXT,
`filename` TEXT
)

‘txid’ es el campo para almacenar el id de la transacción que recibimos de Nxt cuando la transacción es aceptada. Es único. ‘hash’ es el hash sha256 del archivo.

En este tutorial me voy a saltar la parte del código de subida de archivos para hacerlo más breve.

Vamos a suponer que el archivo ya ha sido subido y almacenado en el servidor web. Definimos la variable para la ubicación del archivo en el código:

$uploadDir = "/home/lurker10/phptutorial/tmp/";
$fileName = "copy12345.tar";

Por defecto, el servidor Nxt recibe las solicitudes API en el puerto 7876. Si lo estás ejecutando en la misma máquina que tu código php, tu código debe enviar solicitudes a http://127.0.0.1:7876/nxt

Las otras variables importantes son la contraseña de la cuenta de Nxt que has creado y dotado de fondos previamente, así como la cuenta del receptor.

Puedes enviarte un mensaje a ti mismo, puesto que el receptor puede ser tu misma cuenta.

$host = "http://127.0.0.1:7876/nxt";
$secretPhrase = "tu contraseña";
$recipientID = "NXT-XXXX-XXXX-XXXX-XXXXX";

La siguiente parte del código es la función que envía la consulta usando curl en una solicitud POST.

Para hacer una solicitud debemos definir las variables $payload y $payload_string y después alimentarlas para sendRequest(). Es posible ejecutar el Nxt Server sobre HTTPS y usar curl para verificar el certificado SSL, pero para hacer esta app más sencilla hemos desactivado la verificación SSL en la conexión curl.

Otro punto de interés es la descripción de $error, con descodificado json desde la respuesta del servidor.

Si hay un problema con la solicitud (“No hay fondos suficientes” en tu cuenta cuando el saldo es cero), tienes que añadir una rutina para el manejo de los errores. Voy a omitir esto también. Para esta app asumo que el servidor responde como corresponde, y devuelve la respuesta a la aplicación para su posterior procesado.

function sendRequest($host, $payload, $payload_string) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 10000);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 10000);
curl_setopt($ch, CURLOPT_POST, count($payload));
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_string);
$output = curl_exec($ch);
$curl_error = curl_error($ch);
curl_close($ch);
$errorDescription = trim(@json_decode($output)->errorDescription);
if ($errorDescription != "") { // perform error handling; return false; }
return $output;
}

Puesto que este archivo ya ha sido subido, creo un hash a sha256 del archivo y su marca de tiempo (timestamp):

$fileHash = hash_file("sha256", $uploadDir.$fileName);
$txTime = time();

Usaré PDO para trabajar con la base de datos.

Abre la base de datos e inserta una nueva entrada.

No sabemos el txid (identificador de transacción) hasta que hablamos con el servidor Nxt, que nos lo puede dar cuando la transacción ha sido aceptada en la red Nxt, así que por el momento insertar null para el txid.

$pdo = new PDO('sqlite:/home/lurker10/phptutorial/files.db');
$sql = "INSERT INTO files (txid, hash, uploadtime, filename)
VALUES (null, '$fileHash', '$txTime', '$fileName')";
$result = $pdo->exec($sql);

A continuación una solicitud para el envío al servidor Nxt.

Esta solicitud en particular es “sendMessage”. Puedes encontrar muchas más solicitudes con las que interactuar con la blockchain y sus parámetros obligatorios y opcionales en:

https://nxtwiki.org/wiki/The_Nxt_API.

Como ya he dicho antes, la fee por transacción es de 1NXT. 1 NXT = 100,000,000 NQT (nanoquantos).

1 NQTes la unidad más pequeña con la que se puede denominar a Nxt, similar a 1 satoshi en Bitcon.

El servidor Nxt acepta la fee en NQT, así que pagamos exactamente 100 millones de NQT (0,03$).

El parámetro “broadcast” se puede cambiar a false, en cuyo caso recibirás  ‘transactionBytes’ en la respuesta, que puede ser emitida a la red más adelante usando la petición ‘broadcastTransaction’. Pero en esta ocasión lo he fijado en ‘true’  para emitir la transacción instantáneamente.

Recuerda dotar de urlencode() al mensaje. Yo inserto el nombre de archivo en el mensaje separado del hash con una columna.

$payload = array(
"requestType" => "sendMessage",
"recipient" => $recipientID,
"secretPhrase" => urlencode($secretPhrase),
"feeNQT" => 100000000,
"deadline" => 1440,
"broadcast" => "true",
"message" => urlencode($fileName . ":" . $fileHash),
"messageIsPrunable" => "true"
);
$payload_string = "";
foreach ($payload as $key => $value) {
$payload_string .= $key . "=" . $value . "&";
}
rtrim($payload_string, "&");

Envía la petición al servidor NXT usando la función sendRequest():

$output = sendRequest($host, $payload, $payload_string);

y decodifica la respuesta JSON del servidor para obtener el identificador de la transacción:

if ($output != false) {
$txId = json_decode($output)->transaction;
}

Ahora que tenemos una respuesta positiva de la transacción aceptada y su ID es conocido, vamos a actualizar el registro en la base de datos local:

$lastId = $pdo->lastInsertId();
$sql = "UPDATE files SET txid = '$txId' where id = '$lastId'";
$result = $pdo->exec($sql);

Opcionalmente podemos proporcionar estos links a los clientes para consultas futuras y para demostrar que el hash ha sido subido:

echo "NXT Transaction ID: " . $txId . ",
JSON response";
echo "

Usa estos links para verificar el hash Sha256 del archivo guardado en tu base de datos local en lugar de un registro permanente en la blockchain de Nxt:

" . $fileHash;

Opcionalmente puedes enviarles por email a los clientes el $txId que podrán utilizar en un futuro para verificar el hash o, de algún otro modo más, proporcionales información acerca de como en un futuro recuperar información del hash de la base de datos propia y compararla con el hash almacenado en la blockchain, por el timestamp o por otro criterio.

Esta app no incluye autenticación del usuario. Normalmente el cliente o usuario de un servicio de intranet será capaz de ver sus archivos después de haberse autentificado en el sitio.

Esta aplicación también asume que la aplicación de verificación está fuera del alcance del que mantiene la base de datos interna, para evitar engaños en los datos de los resultados de verificación.

Ahora el registro es almacenado en la base de datos de la compañía. Muestra el registro de la base de datos para confirmar que se encuentra allí:

$sth = $pdo->prepare("SELECT id, txid, hash, uploadtime, filename FROM files ORDER BY id DESC");
$sth->execute();
$result = $sth->fetch(PDO::FETCH_OBJ);
if ($result != false) {
var_dump($result);
}

La aplicación de verificación

Para usar la verificación por hash el cliente tiene que tener el ID de la transacción en la blockchain de Nxt aprobada por ellos cuando la transacción fue enviada a la blockchain de Nxt.

Supongamos que el cliente la tiene, almacenada en el email o recuperada de algún otro modo. Aquí está:

$txId = "111111111111111111";

Vamos a ver lo que nuestra base de datos propia tiene para el hash del archivo. Busca y guarda en $hashInDb.

$pdo = new PDO('sqlite:/home/lurker10/phptutorial/files.db');
$sth = $pdo->prepare("SELECT hash FROM files where txid = '$txId'");
$sth->execute();
$result = $sth->fetch(PDO::FETCH_OBJ);
if ($result != false) {
$hashInDb = $result->hash;
}

Envía una petición al servidor NXT y busca toda la información almacenada en la blockchain de Nxt para transacciones con ese ID.

$payload = array (
"requestType" => "getTransaction",
"transaction" => $txId
);
$payload_string = "";
foreach ($payload as $key => $value) {
$payload_string .= $key . "=" . $value . "&";
}
rtrim($payload_string, "&");

$output = sendRequest($host, $payload, $payload_string);

Decodifica la respuesta JSON y extrae el campo añadido dónde se almacena el hash.

En la primera parte de la app nosotros almacenamos el nombre del archivo separado del hash con una columna. Ahora extraemos sólo la porción correspondiente al hash del mensaje arbitrario

$attachmentPlainData = json_decode($output)->attachment->message;
$hashInBlockchain = explode(":", $attachmentPlainData)[1];

Y compara lo que tenemos en la base de datos de la compañía con lo que fue almacenado hace 1 año en la blockchain de Nxt:

if ($hashInDb == $hashInBlockchain)
echo "Hashes are identical";
else
echo "Hashes are not identical";

NXT-crypto-developer