Usando JavaScript para acceder a los índices secundarios en las tablas de un smart contract en WAX

Posted on

Las tablas en las que vamos a almacenar la información de nuestros contratos inteligentes en una cadena de tipo EOSio, como WAX Blockchain, pueden tener hasta un total de 20 índices para facilitar el acceso a los datos. Hay que tener en cuenta algunas cuestiones previas:

  • Lo más importante a tener en cuenta es que cada índice debe referirse a un contenido numérico entero. (El valor de un campo tipo name puede considerarse numérico gracias a la serialización de los nombres de cuenta)
  • El índice primario debe ser único; el resto de índices no tienen por qué ser únicos.

Para ilustrar esta explicación voy a utilizar una de las tablas que contiene mi contrato inteligente para la casa de subastas WAX Arena, sobre WAX Blockchain.

En esta tabla se guarda la información de las subastas activas y, como es de suponer, será la tabla más consultada y de todas las formas posibles. He tratado de anticiparme a las necesidades de consulta mediante la creación de 8 índices:

  • primary_key: Índice principal y de clave única (sin repeticiones). Permite acceder a la tabla por el ID de subasta.
  • getasset: Permite acceder a la tabla a través de los ID de los assets.
  • getowner: Permite acceder a la tabla a través de los nombres de los propietarios (quienes han creado la subasta)
  • getbidder: Permite acceder a la tabla a través de los nombres del pujante actual (máximo pujante y candidato a ganador del token).
  • getdate: El acceso a la tabla se hace por la fecha de creación de subasta (formato UNIX).
  • getfinish: Utiliza el tiempo de duración de las subastas como campo de búsqueda y acceso.
  • getbids: A través de este índice podemos consultar el número de pujas de cada subasta activa.
  • getvalue: Permite acceder a la tabla por el valor que tendrá la próxima puja. La intención es que permita ordenar el listado teniendo en cuenta su precio, pero si una subasta no tiene pujas ese precio es 0, por lo que he decido tomar como referencia el valor de la siguiente puja a realizar.

Leyendo las subastas activas

Para acceder a las tablas utilizaremos la librería para JavaScript eosjs (https://github.com/EOSIO/eosjs)

Al ejecutar este código accederemos a la tabla ‘activebids’ del contrato inteligente ‘waxarena3dk1’ a través del índice primario, ya que no hemos indicado ningún índice. El listado mostrará hasta los 100 primeros registros de la tabla ordenados por el ID de registro.

Accediendo a través de los índices secundarios de la tabla

Supongamos que queremos acceder a la tabla teniendo en cuenta el valor de los assets subastados. Para ello hemos definido el índice “getvalue” que, si nos fijamos en el código del smart contract, está en la posición 8.

En el JSON de la función get_table_rows debemos añadir la información necesaria respecto al índice que vamos a utilizar:

  • index_postion: Posición que ocupa el índice en el smart contract. En este ejemplo, posición 8
  • key_type: El tipo de dato del índice. En este caso es un entero de 64 bits, que se representa como “i64”

He añadido el parámetro “reverse” para que invierta el orden de búsqueda (de mayor a menor). También he limitado la búsqueda a los 5 primeros registros.

Si quisiéramos obtener un listado ordenado por las subastas más activas tendríamos que recurrir al índice “getbids” (7) y también especificar reverse: true;

Acotando la búsqueda mediante condiciones

Vamos a crear búsquedas más específicas. Ya vimos cómo obtener un listado ordenado por las subastas más activas pero, ahora, vamos a filtrar ese resultado por las subastas que tengan más de 4 pujas.

Ahora entra en juego un nuevo parámetro: lower_bound.

lower_bound buscará los registros cuya clave de indexación solicitada sea mayor o igual al valor indicado.

Esto sería como filtrar con un condicional:

si bid_count >= 4 -> dato válido.

Si queremos filtrar preguntando por valores de clave mayores que la clave indicada podemos utilizar upper_bound. Entonces, si cambiamos en el código:

lower_bound: 4

por

upper_bound: 4

obtendremos subastas con 5 o más pujas.

Si bid_count > 4 -> dato válido

También podemos combinar los dos parámetros en una misma lectura. En este caso el filtro se comportará de un modo especial; comenzará a dar por válidos los registros que pasen el filtro de lower_bound pero no los que cumplan con upper_bound. Veamos un ejemplo:

Con esta configuración podremos acceder a todos las subastas cuyo número de pujas esté comprendido entre 2 y 4, ambos incluídos.

Esta configuración también resulta útil para buscar registros de un valor determinado, como el nombre de un vendedor:

Con este código, estamos filtrando los resultados para aquellas subastas creadas por el usuario “radaquesttcg” gracias al filtro “getowner”, que ocupa la posición 3.

Espero que con estos ejemplos el uso de índices secundarios resulte mucho más sencillo en adelante.