Saltar al contenido principal

Publisher

El publisher guarda un blob en nombre de un cliente que no habla con los nodos de almacenamiento: codifica los datos, paga el almacenamiento y el gas en IOTA con su propia cuenta, sube los slivers, certifica el blob y envía el objeto Blob a la dirección que elija el cliente. También guarda quilts.

URL base: https://publisher.iotastorage.com.

El publisher público pide un token

Como el publisher paga con su propio IOTA, el público pide un token (Authorization: Bearer <token>) y lo usa el proyecto. Sin él, responde 401 UNAUTHENTICATED.

Para guardar tus propios datos, usa la app con tu wallet, o el cliente de referencia en JavaScript: pagas en IOTA y el Blob es tuyo desde el principio. Cualquiera puede leer el resultado con el aggregator público.

MétodoRutaCuerpo
PUT/v1/blobs?<parámetros>Los bytes del blob.
PUT/v1/quilts?<parámetros>Los archivos, como multipart/form-data.

Parámetros​

ParámetroPor defectoQué significa
epochs1Épocas que se guarda el blob: un entero de 1 a 53.
deletable=trueGuarda un blob borrable (por defecto).
permanent=trueGuarda un blob permanente, que no se puede borrar. No junto con deletable=true.
send_object_toel publisherDirección de IOTA (0x…) que recibe el objeto Blob. Sin él, el Blob se queda en la cuenta del publisher.

Guardar un blob​

curl -X PUT "https://publisher.iotastorage.com/v1/blobs?epochs=5&send_object_to=0x<tu dirección>" \
-H "Authorization: Bearer $TOKEN" \
--upload-file archivo

La respuesta describe el Blob nuevo. Por ejemplo, para un archivo de 1 MiB guardado 5 épocas desde la época 1:

{
"newlyCreated": {
"blobObject": {
"id": "0x…",
"registeredEpoch": 1,
"blobId": "<blob ID>",
"size": 1048576,
"encodingType": "RS2",
"certifiedEpoch": 1,
"storage": {
"id": "0x…",
"startEpoch": 1,
"endEpoch": 6,
"storageSize": 5309400
},
"deletable": true
},
"resourceOperation": {
"registerFromScratch": { "encodedLength": 5309400, "epochsAhead": 5 }
},
"cost": 42000
}
}
CampoQué es
blobObject.idID del objeto Blob en IOTA.
blobObject.blobIdEl blob ID, para leerlo con el aggregator.
blobObject.sizeTamaño de los datos originales, en bytes.
blobObject.storageEl recurso Storage: épocas y tamaño codificado reservado.
resourceOperation.registerFromScratch.encodedLengthTamaño codificado que se pagó.
costLo que cobró el contrato por el almacenamiento, en nanos de IOTA (sin el gas).

Guardar un quilt​

PUT /v1/quilts guarda varios archivos como un solo quilt. El cuerpo es multipart/form-data:

  • cada campo es un archivo, y el nombre del campo es su identificador en el quilt (no puede empezar por _);
  • un campo _metadata opcional lleva una lista JSON de { "identifier", "tags" } con etiquetas de texto para algunos de los archivos.
curl -X PUT "https://publisher.iotastorage.com/v1/quilts?epochs=5" \
-H "Authorization: Bearer $TOKEN" \
-F "index.html=@index.html" \
-F "logo.svg=@logo.svg" \
-F '_metadata=[{"identifier": "logo.svg", "tags": {"kind": "image"}}]'
{
"blobStoreResult": {
"newlyCreated": { "blobObject": { … }, "resourceOperation": { … }, "cost": … }
},
"storedQuiltBlobs": [
{ "identifier": "index.html", "quiltPatchId": "<quilt patch ID>" },
{ "identifier": "logo.svg", "quiltPatchId": "<quilt patch ID>" }
]
}

Después, cada archivo se puede leer con el aggregator por su quilt patch ID. Con 100 shards, un quilt admite hasta 66 archivos.

Límites y comportamiento​

  • Como mucho 10 MiB por petición (el blob o el cuerpo entero del quilt); la red admite blobs de hasta unos 142 MiB con otros clientes. Un blob vacío se rechaza.
  • Las escrituras se atienden de una en una, porque todas pagan con las monedas del publisher.
  • No hay respuesta alreadyCertified: cada PUT registra un Blob nuevo, aunque los datos ya estén guardados.
  • Tiene CORS, y admite las cabeceras authorization y content-type en las peticiones.

Errores​

El mismo formato JSON que el aggregator:

CódigostatusCuándo
400INVALID_ARGUMENTepochs no válido, permanent junto con deletable, send_object_to no válido, blob vacío, cuerpo multipart o _metadata mal formados.
401UNAUTHENTICATEDFalta el token o no es el correcto.
405METHOD_NOT_ALLOWEDMétodo equivocado, o un servidor que solo lee.
413PAYLOAD_TOO_LARGEMás grande que el límite del publisher o que el blob más grande de la red.