Wiki de ZooBC
Datos y almacenamiento

Datasets

Un dataset es la forma más sencilla de poner datos en ZooBC: un pequeño registro, un nombre de propiedad y su valor, que una cuenta escribe bajo una cuenta, normalmente la suya. Cada nodo guarda la fila como parte del estado de la cadena, así que cualquier app puede leerla a través de la API de cualquier nodo. Las apps usan las filas para perfiles, ajustes, avisos de versiones, facturas e iconos de tokens.

Una fila

Una transacción SetupAccountDataset (tipo 3) escribe una fila, cuya clave la forman tres cosas:

  • el autor, la cuenta que envía la transacción;
  • el destinatario, la cuenta bajo la que está la fila, normalmente el propio autor (un destinatario vacío también es una clave válida);
  • la propiedad, un nombre de 1 a 256 bytes, nunca vacío.

El valor contiene hasta 4096 bytes, dentro de un cuerpo de transacción de como máximo 65 536 bytes. Las filas tienen versiones: escribir de nuevo la misma clave sustituye la fila actual, y RemoveAccountDataset (tipo 259) desactiva una fila.

Una fila de dataset: quién la escribió, bajo quién, y la propiedad y su valor, dentro de un objeto que paga alquiler.
Una fila de dataset: quién la escribió, bajo quién, y la propiedad y su valor, dentro de un objeto que paga alquiler.

Una fila es pública: cualquiera puede leerla, así que un dataset no es lugar para un secreto. Tampoco es una forma de guardar un archivo grande. Los archivos pequeños van a los archivos DFS y los grandes al almacenamiento descentralizado.

Importa quién la escribió

Cualquier cuenta puede escribir una fila bajo cualquier destinatario, y al destinatario no se le pregunta, igual que cualquiera puede enviar un pago a cualquier dirección. Por tanto, una fila es una afirmación que hace su autor sobre el destinatario. La cadena demuestra quién lo dijo y cuándo; no puede saber si la afirmación es cierta.

Un nodo lista las filas de una cuenta en GET /api/v1/accounts/<address>/datasets, opcionalmente filtradas con ?property=<prefix>. La lista devuelve todas las filas en las que la dirección es el autor o el destinatario, cada una con su role: autor (setter), destinatario (recipient) o ambos (both). Una app que encuentra «verified = yes» bajo un usuario solo debe aceptarlo cuando el autor es la cuenta en la que confía, como su propia cuenta de verificación, y debe responder «no verificado» cuando no existe ninguna fila así (datos de la cadena son entradas no confiables).

Dos filas dicen «verified = yes»; solo cuenta la escrita por el autor de confianza.
Dos filas dicen «verified = yes»; solo cuenta la escrita por el autor de confianza.

Objetos y propietarios

Cada fila pertenece a un objeto de dataset, nombrado por el hash de la transacción que lo creó. El objeto tiene un propietario (al principio, su creador), un propietario pendiente y un modo de gestión.

  • Ceder un objeto requiere dos pasos. El propietario envía TransferDataset (tipo 42) nombrando al nuevo propietario, y la cadena solo registra un propietario pendiente. La cesión se completa cuando esa cuenta envía AcceptDataset (tipo 44). Un AcceptDataset de cualquier otro, o para un objeto sin propietario pendiente, es una operación nula pagada: se cobra la comisión y no cambia nada. Así, nadie puede endosar un objeto, ni el alquiler que conlleva, a una cuenta que no lo pidió, y el antiguo propietario sigue siéndolo hasta que el nuevo acepta.
  • Borrar. DeleteDataset (tipo 45), enviado por el propietario, desactiva todas las filas del objeto, y el depósito del objeto se lleva al fondo de longevidad.
  • Política. SetDatasetPolicy (tipo 43) guarda en el objeto un modo de gestión (solo el propietario, lista blanca, lista negra o abierto) y una lista de acceso, pero ninguna regla de consenso los lee, así que no restringen nada.

Cada objeto tiene además una dirección de depósito: una cuenta de tipo 10, escrita ZBS_…, cuyos bytes son 0A000000 seguido del id del objeto. Cualquiera puede financiarla con un simple SendZBC, de modo que un grupo de usuarios puede mantener vivo entre todos un registro compartido. Es una cuenta normal con fondos, así que también paga alquiler de cuenta. GET /api/v1/dataset-address/<hash or ZBS_ address> la muestra.

Alquiler

Una vez por periodo de facturación, 172 800 bloques (unos 30 días) en mainnet, la cadena cobra a cada objeto por los bytes de sus filas activas:

bytes = sum of (property + value) over the object's active rows
rent  = ceil(bytes × price per MiB ÷ 1,048,576), then × storage multiplier, rounded up

El precio inicial es de 5 000 000 unidades atómicas (0.05 ZBC) por MiB, y el multiplicador de almacenamiento empieza en 1.0. Un MiB completo de filas paga exactamente 0.05 ZBC por periodo. Una fila con una propiedad de 14 bytes y un valor de 300 bytes, 314 bytes en total, paga 1498 unidades: 314 × 5 000 000 ÷ 1 048 576 da 1497.27, y cada etapa del cobro redondea hacia arriba.

El alquiler se toma primero del depósito y después del saldo del propietario. Si entre ambos no alcanzan para pagar, todas las filas del objeto se desactivan y el depósito que quede va al fondo de longevidad. Al destinatario nunca se le cobra. Todo el alquiler de datasets se abona al fondo de longevidad, que paga a los nodos una porción en cada bloque; el ZBC nunca se quema.

El periodo de facturación sigue al intervalo de instantáneas. El precio lo votan las plazas y puede bajar hasta una unidad atómica; se mueve una vez por ciclo de instantánea, dentro de unos límites, hasta el promedio de los votos de las plazas contadas (votos de precio).

Prefijos reservados

Unos pocos prefijos de propiedad están reservados, y la cadena comprueba sus filas antes de aceptarlas. La prueba compara los bytes en bruto del principio de la propiedad, así que invoice: no es inv:.

PrefijoRegla
dfs: y dfs:dir:solo los escriben los tres tipos de transacción DFS; un SetupAccountDataset ahí se rechaza (archivos en la cadena (DFS))
tokenicon:una imagen PNG o WebP que declara un ancho y un alto de 1 a 512 píxeles, de 16 a 4096 bytes
inv:un objeto JSON sin ningún número negativo en ninguna parte, para que una factura no pueda llevar un importe negativo; se aplica desde el bloque 0

Por tanto, el icono de un token vive en la cadena, dentro de la fila, no detrás de una URL. Ninguna de estas comprobaciones depende de la firma de nadie: todos los nodos aplican la misma regla.

Véase también