{"id":2953,"date":"2025-02-21T18:23:03","date_gmt":"2025-02-21T17:23:03","guid":{"rendered":"https:\/\/djimn.com\/?p=2953"},"modified":"2025-02-21T18:23:03","modified_gmt":"2025-02-21T17:23:03","slug":"utilizando-nem-catapult-para-controlar-multiples-dispositivos-iot","status":"publish","type":"post","link":"https:\/\/djimn.com\/index.php\/2025\/02\/21\/utilizando-nem-catapult-para-controlar-multiples-dispositivos-iot\/","title":{"rendered":"Utilizando NEM Catapult para controlar m\u00faltiples dispositivos IoT"},"content":{"rendered":"<p class=\"has-dark-gray-color has-text-color\">Vamos a cubrir el uso de transacciones agregadas de NEM Catapult para controlar varios dispositivos IoT, tan simples como dos dispositivos y un archivo JavaScript.<\/p>\n<h2 class=\"has-dark-gray-color has-text-color wp-block-heading\">Transacci\u00f3n agregada<\/h2>\n<p class=\"has-dark-gray-color has-text-color\">Las transacciones agregadas fusionan m\u00faltiples transacciones en una, permitiendo <strong>permutas de confianza<\/strong>, y otra l\u00f3gica avanzada. NEM hace esto generando un contrato inteligente desechable de una sola vez. Cuando todas <a class=\"reference internal\" href=\"https:\/\/nemtech.github.io\/concepts\/account.html\"><span class=\"doc\">las cuentas<\/span><\/a> involucradas han firmado la transacci\u00f3n agregada, todas las transacciones internas se ejecutan al mismo tiempo. <strong>Esto es extremadamente crucial si usted est\u00e1 emitiendo una serie de acciones a muchos dispositivos a la vez, una posible aplicaci\u00f3n futura de esto es rob\u00f3tica enjambre (drones, autos autoconducidos, etc). <\/strong>Para el resto de los ejemplos, puedes echarle un echado un echado un ver <a href=\"https:\/\/nemtech.github.io\/concepts\/aggregate-transaction.html\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a>.<\/p>\n<h2><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" class=\"wp-image-3056 alignleft\" src=\"https:\/\/i0.wp.com\/djimn.com\/wp-content\/uploads\/2025\/02\/images2433.png?resize=346%2C175&#038;ssl=1\" alt=\"\" width=\"346\" height=\"175\" srcset=\"https:\/\/i0.wp.com\/djimn.com\/wp-content\/uploads\/2025\/02\/images2433.png?resize=300%2C152&amp;ssl=1 300w, https:\/\/i0.wp.com\/djimn.com\/wp-content\/uploads\/2025\/02\/images2433.png?w=316&amp;ssl=1 316w\" sizes=\"(max-width: 346px) 100vw, 346px\" \/><\/h2>\n<h2 class=\"wp-block-heading\">Controlar m\u00faltiples dispositivos<\/h2>\n<p class=\"has-dark-gray-color has-text-color\">As\u00ed que el concepto es muy simple, utilizando la transacci\u00f3n agregada para enviar mensajes a m\u00faltiples dispositivos a la vez, anunciando una transacci\u00f3n agregada a un nodo, los dispositivos pueden leer la \u00faltima transacci\u00f3n de acuerdo con la direcci\u00f3n de una cuenta, y hacer la acci\u00f3n apropiada basada en el mensaje en el nodo.<\/p>\n<p class=\"has-dark-gray-color has-text-color\">Para una demostraci\u00f3n simple, decid\u00ed utilizar dispositivos ESP8266 para controlar un LED mediante el uso de GET a trav\u00e9s de REST API, se pueden a\u00f1adir nuevas mejoras mediante rel\u00e9s para controlar ventiladores u otros aparatos el\u00e9ctricos, etc.<\/p>\n<p><strong>Instalaci\u00f3n y Configuraci\u00f3n:<\/strong><\/p>\n<p>1.- Descargar e instalar llave p\u00fablico del repositorio<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build\/bin# wget -qO - https:\/\/www.mongodb.org\/static\/pgp\/server-4.2.asc | sudo apt-key add -<\/pre>\n<p><span id=\"more-2720\"><\/span><br \/>\n2.- Crear archivo de configuraci\u00f3n con el repositorio<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build\/bin# echo \"deb [ arch=amd64 ] https:\/\/repo.mongodb.org\/apt\/ubuntu bionic\/mongodb-org\/4.2 multiverse\" | sudo tee \/etc\/apt\/sources.list.d\/mongodb-org-4.2.list<\/pre>\n<p>3.- Descargar e instalar llave p\u00fablico del repositorio<\/p>\n<pre>root@catapult:\/opt# curl -sS https:\/\/dl.yarnpkg.com\/debian\/pubkey.gpg | sudo apt-key add -<\/pre>\n<p>4.- Generar archivo configuraci\u00f3n repositorio<\/p>\n<pre>root@catapult:\/opt# echo \"deb https:\/\/dl.yarnpkg.com\/debian\/ stable main\" | sudo tee \/etc\/apt\/sources.list.d\/yarn.list<\/pre>\n<p>5.- Actualizar repositorio:<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build\/bin# aptitude update<\/pre>\n<p>6.- Instalar mongodb-org<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build\/bin# aptitude install -y mongodb-org<\/pre>\n<p>7.- Iniciar servicio<\/p>\n<pre>root@catapult:\/usr\/share\/doc\/mongodb-org# service mongod start<\/pre>\n<p>8.- Comprobar inicio del servicio<\/p>\n<pre>root@catapult:\/usr\/share\/doc\/mongodb-org# netstat -putan<\/pre>\n<pre>Active Internet connections (servers and established)\r\nProto Recv-Q Send-Q Local Address           Foreign Address         State       PID\/Program name    \r\ntcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1722\/sshd           \r\ntcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      11092\/mongod        \r\n<\/pre>\n<p>9.- Instalar YARN<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# aptitude install -y yarn<\/pre>\n<p>10.- Comprobar versi\u00f3n instalada<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# yarn --version<\/pre>\n<pre>1.19.0\r\n<\/pre>\n<p>11.- Instalar paquete NodeJs<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# aptitude install -y nodejs<\/pre>\n<p>12.- Comprobar versi\u00f3n instalada<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# nodejs --version<\/pre>\n<pre>v8.10.0\r\n<\/pre>\n<p>13.- Mostrar el contenido del archivo \u00abcatapult.address.txt\u00bb<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build\/# cat \/opt\/catapult-server\/_build\/catapult.address.txt<\/pre>\n<pre>--- generating 10 keys ---\r\nCuenta: 1\r\n           private key: A1A11A805D7BA84B8E32DBC45A1600C4BD1797666D0BFA6F1FB52EE5380CECC7\r\n            public key: 9E02BF613B9FB9024D2D2EC937FEE4661B2C3CCF7E94383D30C9D368D598CC05\r\n  address (mijin-test): SDXUNVIIXWDVRRQZBYAOPLTZV5N7BO3N5W4M7EMD\r\n\r\nCuenta: 2\r\n           private key: EB15E39C761AA8D3793C5DC1681972CAA1997FB5F8712B62A5A329525193D2A9\r\n            public key: 566AA340077460B6A486D9914A948DF7CFB9DFF731844232E33F6608CA6DC734\r\n  address (mijin-test): SCPZ2IJFIBBJX5SQIOXVPSPA4Z3EH3RQRQLAUJ52\r\n\r\nCuenta: 3\r\n           private key: 36B46E3FFBC9EF29C0F5C744A9CD41EEB35B18C14CF30ED6AAD0AFE2FC7911F8\r\n            public key: \t\r\n  address (mijin-test): SDFUE4C3KJQJBUNEXJNDDCSMLFCQQHPOL5IBIHXY\r\n\r\ncuenta: 4\r\n           private key: E9A45B28545E4DE720443CFD71E43F706C6ACFF539AA9234AFFE8117ED597A5E\r\n            public key: CFB9E33C6BF5A11D7430641CD78A5CB7F17C48D47C2432428774D7209E2940D7\r\n  address (mijin-test): SBEUAR3RPE5GYQTUBJW3BQ6YV3ZLFSWAJIVAMLRF\r\n........\r\n<\/pre>\n<p>14.- Editar archivo de configuraci\u00f3n Harvesting<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# vim \/opt\/catapult-server\/_build\/resources\/config-harvesting.properties<\/pre>\n<p>14.1.- Colocar en <strong>\u00abharvesterPrivateKey\u00bb<\/strong> el contenido de <strong>\u00abprivate key\u00bb<\/strong> de lo generado en el archivo <strong>\u00abroot@catapult:\/opt\/catapult-server\/_build# catapult.address.txt\u00bb<\/strong> en \u00e9ste caso se coloc\u00f3 la 3era cuenta <strong>(ver punto 13)<\/strong><\/p>\n<pre>[harvesting]\r\nharvesterPrivateKey = 36B46E3FFBC9EF29C0F5C744A9CD41EEB35B18C14CF30ED6AAD0AFE2FC7911F8\r\n<\/pre>\n<p>Activar el \u00abAutoHarvesting\u00bb<\/p>\n<pre>enableAutoHarvesting = true\r\n<\/pre>\n<p>15.- Editar el archivo de configuraci\u00f3n del nodo<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# vim \/opt\/catapult-server\/_build\/resources\/config-user.properties<\/pre>\n<p>15.1.- Colocar en <strong>\u00abbootPrivateKey\u00bb<\/strong> el contenido de <strong>\u00abprivate key\u00bb<\/strong> de lo generado en el archivo <strong>\u00abroot@catapult:\/opt\/catapult-server\/_build# catapult.address.txt\u00bb<\/strong>, pero que sea distinto al utilizado en la configuraci\u00f3n del <strong>\u00abharvesterPrivateKey\u00bb<\/strong>, en \u00e9ste caso se coloc\u00f3 la 2da cuenta <strong>(ver punto 13)<\/strong><\/p>\n<pre>[account]\r\n  \r\nbootPrivateKey = EB15E39C761AA8D3793C5DC1681972CAA1997FB5F8712B62A5A329525193D2A9\r\nshouldAutoDetectDelegatedHarvesters = true\r\n\r\n[storage]\r\n\r\ndataDirectory = ..\/data\r\npluginsDirectory = .\r\n<\/pre>\n<p>16.- Editar el archivo de configuraci\u00f3n de las propiedades del nodo<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# vim \/opt\/catapult-server\/_build\/resources\/config-node.properties<\/pre>\n<p>Efectuar el siguiente cambio:<\/p>\n<pre>[localnode]\r\n....\r\nroles = Api\r\n<\/pre>\n<p>17.- Editar el archivo de configuraci\u00f3n de las extensiones del servidor<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# vim \/opt\/catapult-server\/_build\/resources\/config-extensions-server.properties<\/pre>\n<p>Efectuar los siguientes cambios:<\/p>\n<pre># api extensions\r\nextension.partialtransaction = true\r\n\r\n# addressextraction must be first because mongo and zeromq depend on extracted addresses\r\nextension.addressextraction = true\r\nextension.mongo = true\r\nextension.zeromq = true\r\n<\/pre>\n<p>18.- Eliminar el contenido de del directorio data<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# rm -rf \/opt\/catapult-server\/_build\/data\/*<\/pre>\n<p>19.- Eliminar el contenido de directorio mijin-test<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# rm -rf \/opt\/catapult-server\/seed\/mijin-test\/*<\/pre>\n<p>20.- Crear directorio \u00ab00000\u00bb<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# mkdir -p \/opt\/catapult-server\/seed\/mijin-test\/00000<\/pre>\n<p>21.- Crear archivo de hash<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# echo -n 6b23c0d5f35d1b11f9b683f0b0a617355deb11277d91ae091d399c655b87940d3f39d5c348e5b79d06e842c114e6cc571583bbf44e4b0ebfda1a01ec05745d43 &gt; \/opt\/catapult-server\/seed\/mijin-test\/00000\/hashes.dat<\/pre>\n<p>22.- Generar bloques nemesis<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# .\/catapult.tools.nemgen --nemesisProperties ..\/resources\/mijin-test.properties<\/pre>\n<p><strong>Nota: Ac\u00e1 generar\u00e1 un error:<\/strong><\/p>\n<pre>2019-10-02 14:25:01.125902 0x00007f2d765ff740:  (io::FileBasedStorage.cpp@108) Throwing exception: hashes.dat has invalid size (0)\r\n<\/pre>\n<p>23.- Copiar el contenido del directorio \u00abmijin-test\u00bb a la carpeta \u00abdata\u00bb<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build# cp \/opt\/catapult-server\/seed\/mijin-test\/00000\/00001.dat \/opt\/catapult-server\/_build\/data\/00000<\/pre>\n<pre>root@catapult:\/opt\/catapult-server\/_build# cp \/opt\/catapult-server\/seed\/mijin-test\/00000\/00001.dat \/opt\/catapult-server\/_build\/data\/00000\/00000.dat<\/pre>\n<p>24.- Ejecutar catapult-server<\/p>\n<pre>root@catapult:\/opt\/catapult-server\/_build\/bin# .\/catapult.server<\/pre>\n<p><strong>Instalar Catapult-Rest<\/strong><\/p>\n<div class=\"wordads-ad-wrapper wordads-ad-wrapper--inline\">\n<div class=\"wordads-ad\">\n<div class=\"wordads-ad-title\"><\/div>\n<div id=\"wordads-ad-771304\" class=\"wordads-ad-content\"><\/div>\n<div class=\"wordads-ad-controls\"><\/div>\n<\/div>\n<\/div>\n<p>25.- Descargar las fuentes<\/p>\n<pre>root@catapult:\/opt# git clone https:\/\/github.com\/nemtech\/catapult-rest.git<\/pre>\n<p>26.- Entrar al directorio de las fuentes descargadas<\/p>\n<pre>root@catapult:\/opt# cd catapult-rest\/<\/pre>\n<p>27.- Ejecutar el script yarn_setup.sh<\/p>\n<pre>root@catapult:\/opt\/catapult-rest# .\/yarn_setup.sh<\/pre>\n<pre>...........\r\nyarn install v1.19.0\r\n[1\/4] Resolving packages...\r\n[2\/4] Fetching packages...\r\n[3\/4] Linking dependencies...\r\nwarning \" &gt; eslint-config-airbnb@17.1.1\" has incorrect peer dependency \"eslint@^4.19.1 || ^5.3.0\".\r\nwarning \"eslint-config-airbnb &gt; eslint-config-airbnb-base@13.2.0\" has incorrect peer dependency \"eslint@^4.19.1 || ^5.3.0\".\r\n[4\/4] Building fresh packages...\r\nDone in 5.17s.\r\nyarn install v1.19.0\r\n[1\/4] Resolving packages...\r\n[2\/4] Fetching packages...\r\n[3\/4] Linking dependencies...\r\nwarning \" &gt; eslint-config-airbnb@17.1.1\" has incorrect peer dependency \"eslint@^4.19.1 || ^5.3.0\".\r\nwarning \"eslint-config-airbnb &gt; eslint-config-airbnb-base@13.2.0\" has incorrect peer dependency \"eslint@^4.19.1 || ^5.3.0\".\r\n[4\/4] Building fresh packages...\r\nDone in 2.63s.\r\n<\/pre>\n<p>28.- Acceder a la carpeta \u00abrest\u00bb<\/p>\n<pre>root@catapult:\/opt\/catapult-rest# cd rest\/<\/pre>\n<p>29.- Efectuar la instalaci\u00f3n de yarn<\/p>\n<pre>root@catapult:\/opt\/catapult-rest\/rest# yarn build<\/pre>\n<pre>yarn run v1.19.0\r\n$ ncp src\/ _build\r\nDone in 0.53s.\r\n<\/pre>\n<p>30.- Editar el archivo de configuraci\u00f3n<\/p>\n<pre>root@catapult:\/opt\/catapult-rest\/rest# vim resources\/rest.json<\/pre>\n<p>30.1.- En la variable <strong>\u00abclientPrivateKey\u00bb<\/strong> colocar el contenido de <strong>\u00abprivate key\u00bb<\/strong> de lo generado en el archivo <strong>\u00abroot@catapult:\/opt\/catapult-server\/_build# catapult.address.txt\u00bb<\/strong>, en \u00e9ste caso se coloc\u00f3 la 4ta cuenta <strong>(ver punto 13)<\/strong><\/p>\n<p><strong>Antes:<\/strong><\/p>\n<pre>\"clientPrivateKey\": \"0000000000000000000000000000000000000000000000000000000000000000\",\r\n<\/pre>\n<p><strong>Despu\u00e9s:<\/strong><\/p>\n<pre>\"clientPrivateKey\": \"E9A45B28545E4DE720443CFD71E43F706C6ACFF539AA9234AFFE8117ED597A5E\",\r\n<\/pre>\n<p>30.2.- En la variable <strong>\u00abpublicKey\u00bb<\/strong>colocar el contenido de <strong>\u00abpublic key\u00bb<\/strong> de la cuenta utilizada en el archivo de configuraci\u00f3n: <strong>\/opt\/catapult-server\/_build\/resources\/config-user.properties<\/strong> variable <strong>\u00abbootPrivateKey\u00bb<\/strong>, en \u00e9ste se coloc\u00f3 la 2da cuenta <strong>(Ver punto 13)<\/strong><\/p>\n<p><strong>Antes:<\/strong><\/p>\n<pre>\"publicKey\": \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\",\r\n<\/pre>\n<p><strong>Despu\u00e9s:<\/strong><\/p>\n<pre>\"publicKey\": \"566AA340077460B6A486D9914A948DF7CFB9DFF731844232E33F6608CA6DC734\",\r\n<\/pre>\n<p>31.- Ejecutar catapult-rest<\/p>\n<pre>root@catapult:\/opt\/catapult-rest\/rest\/_build# node index.js<\/pre>\n<pre>[winston] Attempt to write logs with no transports {\"message\":\"loading config from ..\/resources\/rest.json\",\"level\":\"info\"}\r\ninfo: loading config from ..\/resources\/rest.json\r\nverbose: finished loading rest server config {\"network\":{\"name\":\"mijinTest\",\"description\":\"catapult development network\"},\"port\":3000,\"crossDomain\":{\"allowedHosts\":[\"*\"],\"allowedMethods\":[\"GET\",\"POST\",\"PUT\",\"OPTIONS\"]},\"clientPrivateKey\":\"E9A45B28545E4DE720443CFD71E43F706C6ACFF539AA9234AFFE8117ED597A5E\",\"extensions\":[\"accountLink\",\"accountRestrictions\",\"aggregate\",\"lockHash\",\"lockSecret\",\"mosaic\",\"mosaicRestrictions\",\"metadata\",\"multisig\",\"namespace\",\"receipts\",\"transfer\"],\"db\":{\"url\":\"mongodb:\/\/localhost:27017\/\",\"name\":\"catapult\",\"pageSizeMin\":10,\"pageSizeMax\":100,\"pageSizeStep\":25,\"maxConnectionAttempts\":5,\"baseRetryDelay\":500},\"apiNode\":{\"host\":\"127.0.0.1\",\"port\":7900,\"publicKey\":\"566AA340077460B6A486D9914A948DF7CFB9DFF731844232E33F6608CA6DC734\",\"timeout\":1000},\"websocket\":{\"mq\":{\"host\":\"127.0.0.1\",\"port\":7902,\"monitorInterval\":500,\"connectTimeout\":10000,\"monitorLoggingThrottle\":60000},\"allowOptionalAddress\":true},\"throttling\":{\"burst\":20,\"rate\":5},\"logging\":{\"console\":{\"formats\":[\"colorize\",\"simple\"],\"level\":\"verbose\",\"handleExceptions\":true},\"file\":{\"formats\":[\"prettyPrint\"],\"level\":\"verbose\",\"handleExceptions\":true,\"filename\":\"catapult-rest.log\",\"maxsize\":20971520,\"maxFiles\":100}},\"timestamp\":\"2019-10-03T01:56:39.635Z\"}\r\ninfo: connecting to mongodb:\/\/localhost:27017\/ (database:catapult) {\"timestamp\":\"2019-10-03T01:56:39.635Z\"}\r\nverbose: connected to mongo at mongodb:\/\/localhost:27017\/catapult {\"timestamp\":\"2019-10-03T01:56:39.687Z\"}\r\ninfo: registering routes {\"timestamp\":\"2019-10-03T01:56:39.689Z\"}\r\ninfo: listening on port 3000 {\"timestamp\":\"2019-10-03T01:56:39.731Z\"}\r\n<\/pre>\n<p>32.- Efectuar pruebas de conexi\u00f3n<\/p>\n<pre>root@catapult:\/home\/operador# curl http:\/\/localhost:3000\/block\/1<\/pre>\n<pre>{\"meta\":{\"hash\":\"DFC5BA2DCF1F3D174C389BF0E87B432D69B4B6D6080CDEE4D05C69C68DC668C9\",\r\n\"generationHash\":\"57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6\",\r\n\"totalFee\":\"0\",\"stateHashSubCacheMerkleRoots\":[],\"numTransactions\":31},\r\n \"block\":{\"signature\":\"5F17EFD6E7533F02492779A07FF57DAD914E97B9DB2FE49AE61E3D7225A2E7E652A5E8A80B494359D97D3BEA12B891689FCCB4EFC7CA088DF295400DE8A39C0A\",\r\n\"signerPublicKey\":\"B4F12E7C9F6946091E2CB8B6D3A12B50D17CCBBF646386EA27CE2946A7423DCF\",\"version\":36867,\r\n\"type\":32835,\"height\":\"1\",\"timestamp\":\"0\",\"difficulty\":\"100000000000000\",\"feeMultiplier\":0,\r\n\"previousBlockHash\":\"0000000000000000000000000000000000000000000000000000000000000000\",\r\n\"transactionsHash\":\"220528A0204E98ACFCC864F24AFC4FBB4AC1D2EDBFB73682E792411F2A93C566\",\r\n\"receiptsHash\":\"6CD06139619DFC894215706DBCE94F020E99F6A970087103B8E04101215CD1ED\",\r\n\"stateHash\":\"61353F97CD7C6B3FC1799E6530A5C1B0BA92E469D30D79856BF0FB2A43BD42BB\",\r\n\"beneficiaryPublicKey\":\"B4F12E7C9F6946091E2CB8B6D3A12B50D17CCBBF646386EA27CE2946A7423DCF\"}}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Vamos a cubrir el uso de transacciones agregadas de NEM Catapult para controlar varios dispositivos IoT, tan simples como dos dispositivos y un archivo JavaScript. Transacci\u00f3n agregada Las transacciones agregadas fusionan m\u00faltiples transacciones en una, permitiendo permutas de confianza, y otra l\u00f3gica avanzada. NEM hace esto generando un contrato inteligente desechable de una sola vez.&hellip; <\/p>\n","protected":false},"author":1,"featured_media":3055,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"_joinchat":[],"footnotes":""},"categories":[5],"tags":[38,39,36,41,37,40],"class_list":["post-2953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech","tag-catapult","tag-devices","tag-iot","tag-javascript","tag-nem","tag-npm"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/djimn.com\/wp-content\/uploads\/2025\/02\/nem-intro-social.jpg?fit=1200%2C630&ssl=1","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/posts\/2953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/comments?post=2953"}],"version-history":[{"count":2,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/posts\/2953\/revisions"}],"predecessor-version":[{"id":3057,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/posts\/2953\/revisions\/3057"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/media\/3055"}],"wp:attachment":[{"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/media?parent=2953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/categories?post=2953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/djimn.com\/index.php\/wp-json\/wp\/v2\/tags?post=2953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}