{"id":38856,"date":"2019-10-31T22:26:22","date_gmt":"2019-10-31T19:26:22","guid":{"rendered":"https:\/\/prohoster.info\/blog\/publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume\/"},"modified":"2019-10-31T22:26:22","modified_gmt":"2019-10-31T19:26:22","slug":"publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume","title":{"rendered":"Teste p\u00fablico: solu\u00e7\u00e3o para privacidade e escalabilidade no Ethereum","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><b>Blockchain<\/b> \u2014 uma tecnologia inovadora que promete melhorar muitas \u00e1reas da vida humana. Ela traz processos e produtos reais para o espa\u00e7o digital, assegura a rapidez e confiabilidade das opera\u00e7\u00f5es financeiras, reduz seus custos e permite ainda criar aplicativos DAPP modernos utilizando contratos inteligentes em redes descentralizadas.<\/p>\n<p>Considerando as in\u00fameras vantagens e diversas \u00e1reas de aplica\u00e7\u00e3o do blockchain, pode parecer estranho que essa tecnologia promissora ainda n\u00e3o tenha se infiltrado em todos os setores. O problema \u00e9 que os blockchains descentralizados modernos carecem de escalabilidade. O Ethereum processa cerca de 20 transa\u00e7\u00f5es por segundo, o que n\u00e3o \u00e9 suficiente para atender \u00e0 demanda dos neg\u00f3cios din\u00e2micos atuais. Ao mesmo tempo, as empresas que utilizam a tecnologia blockchain hesitam em abandonar o Ethereum devido ao seu alto n\u00edvel de prote\u00e7\u00e3o contra invas\u00f5es e falhas de rede.<\/p>\n<p>Para garantir descentraliza\u00e7\u00e3o, seguran\u00e7a e escalabilidade no blockchain, resolvendo assim a Trilogia da Escalabilidade, a equipe de desenvolvedores <noindex><a rel=\"nofollow\" href=\"https:\/\/opporty.com\/\">Opporty<\/a><\/noindex> criou o Plasma Cash \u2014 uma cadeia lateral composta por um contrato inteligente e uma rede privada baseada em Node.js, que periodicamente transmite seu estado para a cadeia raiz (Ethereum).<\/p>\n<p><img decoding=\"async\" alt=\"Teste p\u00fablico: solu\u00e7\u00e3o para privacidade e escalabilidade no Ethereum\" src=\"\/wp-content\/uploads\/2019\/10\/02cc45df3474179d0936c2a86fb7dee3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Processos-chave no Plasma Cash<\/h2>\n<p>\n<b>1. <\/b>O usu\u00e1rio chama a fun\u00e7\u00e3o do contrato inteligente `deposit`, passando o valor em ETH que deseja colocar no token Plasma Cash. A fun\u00e7\u00e3o do contrato inteligente cria o token e gera um evento sobre isso.<\/p>\n<p><b>2. <\/b>Os n\u00f3s do Plasma Cash, inscritos nos eventos do contrato inteligente, recebem o evento de cria\u00e7\u00e3o do dep\u00f3sito e adicionam a transa\u00e7\u00e3o de cria\u00e7\u00e3o do token ao pool.<\/p>\n<p><b>3. <\/b>Periodicamente, n\u00f3s especiais do Plasma Cash pegam todas as transa\u00e7\u00f5es do pool (at\u00e9 1 milh\u00e3o) e formam um bloco a partir delas, calculam a \u00e1rvore de Merkle e, consequentemente, o hash. Este bloco \u00e9 enviado para outros n\u00f3s para verifica\u00e7\u00e3o. Os n\u00f3s checam se o hash de Merkle \u00e9 v\u00e1lido, se as transa\u00e7\u00f5es s\u00e3o v\u00e1lidas (por exemplo, se o remetente do token \u00e9 seu propriet\u00e1rio). Ap\u00f3s a verifica\u00e7\u00e3o do bloco, o n\u00f3 chama a fun\u00e7\u00e3o `submitBlock` do contrato inteligente, que salva na cadeia raiz o n\u00famero e o hash de Merkle do bloco. O contrato inteligente gera um evento sobre a adi\u00e7\u00e3o bem-sucedida do bloco. As transa\u00e7\u00f5es s\u00e3o removidas do pool. <\/p>\n<p><b>4. <\/b>Os n\u00f3s que receberam o evento de submiss\u00e3o do bloco come\u00e7am a aplicar as transa\u00e7\u00f5es que foram adicionadas ao bloco.<\/p>\n<p><b>5. <\/b>Em algum momento, o propriet\u00e1rio (ou n\u00e3o propriet\u00e1rio) do token deseja retir\u00e1-lo do Plasma Cash. Para isso, ele invoca a fun\u00e7\u00e3o `startExit`, passando as informa\u00e7\u00f5es das \u00faltimas 2 transa\u00e7\u00f5es do token, que confirmam que ele \u00e9 o propriet\u00e1rio do token. O contrato inteligente, usando o hash Merkle, verifica a presen\u00e7a das transa\u00e7\u00f5es nos blocos e envia o token para sa\u00edda, que ocorrer\u00e1 em duas semanas.<\/p>\n<p><b>6. <\/b>Se a opera\u00e7\u00e3o de retirada do token ocorreu com viola\u00e7\u00f5es (o token foi gasto ap\u00f3s o in\u00edcio do procedimento de retirada ou o token j\u00e1 pertencia a outra pessoa antes da retirada), o propriet\u00e1rio do token pode contestar a sa\u00edda dentro de duas semanas.<\/p>\n<p><img decoding=\"async\" alt=\"Teste p\u00fablico: solu\u00e7\u00e3o para privacidade e escalabilidade no Ethereum\" src=\"\/wp-content\/uploads\/2019\/10\/0626ca6b010eb847175dbfb0b6d7b357.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>A privacidade \u00e9 alcan\u00e7ada de duas maneiras<\/h2>\n<p>\n<b>1. <\/b>A cadeia raiz n\u00e3o sabe nada sobre as transa\u00e7\u00f5es que s\u00e3o formadas e enviadas dentro da cadeia filha. A informa\u00e7\u00e3o sobre quem depositou e retirou ETH no Plasma Cash permanece p\u00fablica.<\/p>\n<p><b>2. <\/b>A cadeia filha permite organizar transa\u00e7\u00f5es an\u00f4nimas usando zk-SNARKs.<\/p>\n<h2>Pilha tecnol\u00f3gica<\/h2>\n<p><\/p>\n<ul>\n<li>NodeJS<\/li>\n<li>Redis<\/li>\n<li>Etherium<\/li>\n<li>Soild<\/li>\n<\/ul>\n<p><\/p>\n<h2>Testes <\/h2>\n<p>\nDesenvolvendo o Plasma Cash, testamos a velocidade do sistema e obtivemos os seguintes resultados:<\/p>\n<ul>\n<li>at\u00e9 35.000 transa\u00e7\u00f5es por segundo s\u00e3o adicionadas ao pool;<\/li>\n<li>at\u00e9 1.000.000 transa\u00e7\u00f5es podem ser armazenadas em um bloco.<\/li>\n<\/ul>\n<p>\nOs testes foram realizados em 3 servidores seguintes:<\/p>\n<p><i>1. Intel Core i7-6700 Quad-Core Skylake incl. SSD NVMe \u2014 512 GB, 64 GB DDR4 RAM<\/i><br \/>\n Foram levantados 3 n\u00f3s validador de Plasma Cash.<\/p>\n<p><i>2. AMD Ryzen 7 1700X Octa-Core \"Summit Ridge\" (Zen), SSD SATA \u2014 500 GB, 64 GB DDR4 RAM<\/i><br \/>\n Foi levantado um n\u00f3 de ETH na testnet Ropsten.<br \/>\n Foram levantados 3 n\u00f3s validador de Plasma Cash.<\/p>\n<p><i>3. Intel Core i9-9900K Octa-Core incl. SSD NVMe \u2014 1 TB, 64 GB DDR4 RAM<\/i><br \/>\n Foi levantado 1 n\u00f3 de submiss\u00e3o de Plasma Cash.<br \/>\n Foram levantados 3 n\u00f3s validador de Plasma Cash.<br \/>\n Executou-se um teste de adi\u00e7\u00e3o de transa\u00e7\u00f5es na rede Plasma Cash.<\/p>\n<p><b>No total: <\/b>10 n\u00f3s de Plasma Cash em uma rede privada.<\/p>\n<h3>Teste 1<\/h3>\n<p>\nH\u00e1 um limite de 1 milh\u00e3o de transa\u00e7\u00f5es por bloco. Portanto, 1 milh\u00e3o de transa\u00e7\u00f5es v\u00e3o para 2 blocos (j\u00e1 que o sistema consegue pegar uma parte das transa\u00e7\u00f5es e submeter enquanto elas est\u00e3o sendo enviadas).<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"pKwqyGkEgdQ\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/pKwqyGkEgdQ\/hqdefault.jpg\" alt=\"Por que no hosting comum a administra\u00e7\u00e3o do PrestaShop \u00e9 lenta, e no seu n\u00e3o \u00e9?\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nEstado inicial: \u00faltimo bloco #7; 1 milh\u00e3o de transa\u00e7\u00f5es e tokens armazenados na base.<\/p>\n<p>00:00 \u2014 in\u00edcio do script de gera\u00e7\u00e3o de transa\u00e7\u00f5es<br \/>\n01:37 \u2014 1 milh\u00e3o de transa\u00e7\u00f5es criadas e envio iniciado para o n\u00f3<br \/>\n01:46 \u2014 o n\u00f3 de submiss\u00e3o pegou 240 mil transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #8. Tamb\u00e9m vemos que 320 mil transa\u00e7\u00f5es foram adicionadas ao pool em 10 segundos<br \/>\n01:58 \u2014 bloco #8 assinado e enviado para valida\u00e7\u00e3o<br \/>\n02:03 \u2014 o bloco #8 foi validado e a fun\u00e7\u00e3o `submitBlock` do contrato inteligente foi chamada com o hash Merkle e o n\u00famero do bloco<br \/>\n02:10 \u2014 o script de demonstra\u00e7\u00e3o terminou, que enviou 1 milh\u00e3o de transa\u00e7\u00f5es em 32 segundos<br \/>\n02:33 \u2014 os n\u00f3s come\u00e7aram a receber informa\u00e7\u00f5es de que o bloco #8 foi adicionado \u00e0 cadeia raiz e come\u00e7aram a realizar 240 mil transa\u00e7\u00f5es<br \/>\n02:40 \u2014 foram removidas 240 mil transa\u00e7\u00f5es do pool, que j\u00e1 est\u00e3o no bloco #8<br \/>\n02:56 \u2014 o n\u00f3 de submiss\u00e3o pegou do pool as restantes 760 mil transa\u00e7\u00f5es e come\u00e7ou a calcular o hash Merkle e a assinar o bloco #9<br \/>\n03:20 \u2014 todos os n\u00f3s cont\u00eam 1 milh\u00e3o e 240 mil transa\u00e7\u00f5es e tokens<br \/>\n03:35 \u2014 o bloco #9 foi assinado e enviado para valida\u00e7\u00e3o em outros n\u00f3s <br \/>\n03:41 \u2014 ocorreu um erro de rede<br \/>\n04:40 \u2014 o tempo limite expirou ao aguardar a valida\u00e7\u00e3o do bloco #9<br \/>\n04:54 \u2014 o n\u00f3 de submiss\u00e3o pegou do pool as restantes 760 mil transa\u00e7\u00f5es e come\u00e7ou a calcular o hash Merkle e a assinar o bloco #9<br \/>\n05:32 \u2014 o bloco #9 foi assinado e enviado para valida\u00e7\u00e3o em outros n\u00f3s<br \/>\n05:53 \u2014 o bloco #9 foi validado e enviado \u00e0 cadeia raiz<br \/>\n06:17 \u2014 os n\u00f3s come\u00e7aram a receber informa\u00e7\u00f5es de que o bloco #9 foi adicionado \u00e0 cadeia raiz e come\u00e7aram a executar 760 mil transa\u00e7\u00f5es<br \/>\n06:47 \u2014 o pool foi limpo das transa\u00e7\u00f5es que est\u00e3o no bloco #9<br \/>\n09:06 \u2014 todos os n\u00f3s cont\u00eam 2 milh\u00f5es de transa\u00e7\u00f5es e tokens<\/p>\n<h3>Teste 2<\/h3>\n<p>\nH\u00e1 um limite de 350 mil por bloco. Como resultado, temos 3 blocos.<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"mpTfTPKYRIc\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/mpTfTPKYRIc\/hqdefault.jpg\" alt=\"Por que no hosting comum a administra\u00e7\u00e3o do PrestaShop \u00e9 lenta, e no seu n\u00e3o \u00e9?\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nEstado inicial: \u00faltimo bloco #9; no banco est\u00e3o salvas 2 milh\u00f5es de transa\u00e7\u00f5es e tokens<\/p>\n<p>00:00 \u2014 o script de gera\u00e7\u00e3o de transa\u00e7\u00f5es j\u00e1 foi iniciado<br \/>\n00:44 \u2014 1 milh\u00e3o de transa\u00e7\u00f5es foi criado e o envio para o n\u00f3 foi iniciado<br \/>\n00:56 \u2014 o n\u00f3 de submiss\u00e3o pegou do pool 320 mil transa\u00e7\u00f5es e est\u00e1 formando o bloco #10. Tamb\u00e9m vemos que 320 mil transa\u00e7\u00f5es est\u00e3o sendo adicionadas ao pool em 10 segundos<br \/>\n01:12 \u2014 o bloco #10 foi assinado e enviado para outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n01:18 \u2014 o script de demonstra\u00e7\u00e3o terminou, que enviou 1 milh\u00e3o de transa\u00e7\u00f5es em 34 segundos<br \/>\n01:20 \u2014 o bloco #10 foi validado e enviado \u00e0 cadeia raiz <br \/>\n01:51 \u2014 todos os n\u00f3s receberam informa\u00e7\u00f5es da cadeia raiz de que o bloco #10 foi adicionado e come\u00e7am a aplicar 320 mil transa\u00e7\u00f5es<br \/>\n02:01 \u2014 o pool foi limpo de 320 mil transa\u00e7\u00f5es, que foram adicionadas ao bloco #10<br \/>\n02:15 \u2014 o n\u00f3 de submiss\u00e3o pegou do pool 350 mil transa\u00e7\u00f5es e est\u00e1 formando o bloco #11<br \/>\n02:34 \u2014 o bloco #11 foi assinado e enviado para outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n02:51 \u2014 o bloco #11 foi validado e enviado \u00e0 cadeia raiz <br \/>\n02:55 \u2014 o \u00faltimo n\u00f3 executou transa\u00e7\u00f5es do bloco #10<br \/>\n10:59 \u2014 a transa\u00e7\u00e3o com o envio do bloco #9 levou muito tempo na cadeia raiz, mas foi conclu\u00edda e todos os n\u00f3s receberam essa informa\u00e7\u00e3o e come\u00e7aram a processar 350 mil transa\u00e7\u00f5es<br \/>\n11:05 \u2014 o pool foi limpo de 320 mil transa\u00e7\u00f5es, que foram adicionadas ao bloco #11<br \/>\n12:10 \u2014 todos os n\u00f3s cont\u00eam 1 milh\u00e3o e 670 mil transa\u00e7\u00f5es e tokens<br \/>\n12:17 \u2014 o n\u00f3 de envio extraiu 330 mil transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #12<br \/>\n12:32 \u2014 o bloco #12 foi assinado e enviado para outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n12:39 \u2014 o bloco #12 foi validado e enviado para a cadeia raiz <br \/>\n13:44 \u2014 todos os n\u00f3s receberam da cadeia raiz a informa\u00e7\u00e3o de que o bloco #12 foi adicionado e come\u00e7am a aplicar 330 mil transa\u00e7\u00f5es<br \/>\n14:50 \u2014 todos os n\u00f3s cont\u00eam 2 milh\u00f5es de transa\u00e7\u00f5es e tokens<\/p>\n<h3>Teste 3<\/h3>\n<p>\nNo primeiro e no segundo servidores, um n\u00f3 validador foi substitu\u00eddo por um n\u00f3 de envio. <\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"w5QHab3heIc\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/w5QHab3heIc\/hqdefault.jpg\" alt=\"Por que no hosting comum a administra\u00e7\u00e3o do PrestaShop \u00e9 lenta, e no seu n\u00e3o \u00e9?\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\nEstado inicial: \u00faltimo bloco #84; no banco de dados est\u00e3o salvas 0 transa\u00e7\u00f5es e tokens<\/p>\n<p>00:00 \u2014 Iniciados 3 scripts que geram e enviam 1 milh\u00e3o de transa\u00e7\u00f5es cada<br \/>\n01:38 \u2014 1 milh\u00e3o de transa\u00e7\u00f5es criadas e o envio para o n\u00f3 de envio #3 foi iniciado<br \/>\n01:50 \u2014 o n\u00f3 de envio #3 extraiu 330 mil transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #85 (f21). Tamb\u00e9m podemos ver que 350 mil transa\u00e7\u00f5es s\u00e3o adicionadas ao pool em 10 segundos<br \/>\n01:53 \u2014 1 milh\u00e3o de transa\u00e7\u00f5es criadas e o envio para o n\u00f3 de envio #1 foi iniciado<br \/>\n01:50 \u2014 o n\u00f3 de envio #3 extraiu 330 mil transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #85 (f21). Tamb\u00e9m podemos ver que 350 mil transa\u00e7\u00f5es s\u00e3o adicionadas ao pool em 10 segundos<br \/>\n02:01 \u2014 o n\u00f3 de envio #1 extraiu 250 mil transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #85 (65e)<br \/>\n02:06 \u2014 o bloco #85 (f21) foi assinado e enviado para outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n02:08 \u2014 o script de demonstra\u00e7\u00e3o do servidor #3 terminou, que enviou 1 milh\u00e3o de transa\u00e7\u00f5es em 30 segundos<br \/>\n02:14 \u2014 o bloco #85 (f21) foi validado e enviado para a cadeia raiz <br \/>\n02:19 \u2014 o bloco #85 (65e) foi assinado e enviado para outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n02:22 \u2014 1 milh\u00e3o de transa\u00e7\u00f5es criadas e o envio para o n\u00f3 de envio #2 foi iniciado<br \/>\n02:27 \u2014 o bloco #85 (65e) foi validado e enviado para a cadeia raiz <br \/>\n02:29 \u2014 o n\u00f3 de envio #2 extraiu 111855 transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #85 (256).<br \/>\n02:36 \u2014 o bloco #85 (256) foi assinado e enviado para outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n02:36 \u2014 o script de demonstra\u00e7\u00e3o do servidor #1 terminou, que enviou 1 milh\u00e3o de transa\u00e7\u00f5es em 42.5 segundos<br \/>\n02:38 \u2014 o bloco #85 (256) foi validado e enviado para a cadeia raiz<br \/>\n03:08 \u2014 o script do servidor #2 terminou, que enviou 1 milh\u00e3o de transa\u00e7\u00f5es em 47 segundos <br \/>\n03:38 \u2014 todos os n\u00f3s receberam da cadeia raiz a informa\u00e7\u00e3o de que os blocos #85 (f21), #86(65e), #87(256) foram adicionados e come\u00e7am a aplicar 330 mil, 250 mil, 111855 transa\u00e7\u00f5es<br \/>\n03:49 \u2014 o pool foi limpo de 330k, 250k, 111855 transa\u00e7\u00f5es, que foram adicionadas aos blocos #85 (f21), #86(65e), #87(256)<br \/>\n03:59 \u2014 o submit do n\u00f3 #1 retirou 888145 transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #88 (214), o submit do n\u00f3 #2 retirou 750k transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #88 (50a), o submit do n\u00f3 #3 retirou 670k transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #88 (d3b)<br \/>\n04:44 \u2014 o bloco #88 (d3b) foi assinado e enviado a outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n04:58 \u2014 o bloco #88 (214) foi assinado e enviado a outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n05:11 \u2014 o bloco #88 (50a) foi assinado e enviado a outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n05:11 \u2014 o bloco #85 (d3b) foi validado e enviado \u00e0 cadeia principal <br \/>\n05:36 \u2014 o bloco #85 (214) foi validado e enviado \u00e0 cadeia principal <br \/>\n05:43 \u2014 todos os n\u00f3s receberam da cadeia principal a informa\u00e7\u00e3o de que os blocos #88 (d3b), #89(214) foram adicionados e come\u00e7am a aplicar 670k, 750k transa\u00e7\u00f5es<br \/>\n06:50 \u2014 devido \u00e0 perda de conex\u00e3o, o bloco #85 (50a) n\u00e3o foi validado<br \/>\n06:55 \u2014 o submit do n\u00f3 #2 retirou 888145 transa\u00e7\u00f5es do pool e est\u00e1 formando o bloco #90 (50a)<br \/>\n08:14 \u2014 o bloco #90 (50a) foi assinado e enviado a outros n\u00f3s para valida\u00e7\u00e3o<br \/>\n09:04 \u2014 o bloco #90 (50a) foi validado e enviado \u00e0 cadeia principal <br \/>\n11:23 \u2014 todos os n\u00f3s receberam da cadeia principal a informa\u00e7\u00e3o de que o bloco #90 (50a) foi adicionado, e come\u00e7am a aplicar 888145 transa\u00e7\u00f5es. Nesse meio tempo, o servidor #3 j\u00e1 havia aplicado transa\u00e7\u00f5es dos blocos #88 (d3b), #89(214)<br \/>\n12:11 \u2014 todos os pools est\u00e3o vazios<br \/>\n13:41 \u2014 todos os n\u00f3s do servidor #3 cont\u00eam 3 milh\u00f5es de transa\u00e7\u00f5es e tokens<br \/>\n14:35 \u2014 todos os n\u00f3s do servidor #1 cont\u00eam 3 milh\u00f5es de transa\u00e7\u00f5es e tokens<br \/>\n19:24 \u2014 todos os n\u00f3s do servidor #2 cont\u00eam 3 milh\u00f5es de transa\u00e7\u00f5es e tokens <\/p>\n<h2>Obst\u00e1culos<\/h2>\n<p>\nDurante o desenvolvimento do Plasma Cash, encontramos os seguintes problemas, que estamos resolvendo gradualmente:<\/p>\n<p><b>1.<\/b> Conflito de intera\u00e7\u00e3o entre diferentes fun\u00e7\u00f5es do sistema. Por exemplo, a fun\u00e7\u00e3o de adicionar transa\u00e7\u00f5es ao pool bloqueava o funcionamento do submit e da valida\u00e7\u00e3o dos blocos, e vice-versa, o que levava \u00e0 queda da velocidade.<\/p>\n<p><b>2. <\/b>N\u00e3o estava claro como enviar um grande n\u00famero de transa\u00e7\u00f5es e, ao mesmo tempo, minimizar os custos de transfer\u00eancia de dados.<\/p>\n<p><b>3. <\/b>N\u00e3o estava claro como e onde armazenar os dados para alcan\u00e7ar resultados altos.<\/p>\n<p><b>4. <\/b>N\u00e3o estava claro como organizar a rede entre os n\u00f3s, uma vez que o tamanho do bloco com 1 milh\u00e3o de transa\u00e7\u00f5es ocupa cerca de 100 Mb.<\/p>\n<p><b>5.<\/b> Trabalhar em modo monothread interrompe a conex\u00e3o entre os n\u00f3s durante longos c\u00e1lculos (por exemplo, constru\u00e7\u00e3o da \u00e1rvore de Merkle e c\u00e1lculo de seu hash).<\/p>\n<h2>Como lidamos com tudo isso?<\/h2>\n<p>\nA primeira vers\u00e3o do n\u00f3 Plasma Cash era uma esp\u00e9cie de combina\u00e7\u00e3o que podia fazer tudo ao mesmo tempo: aceitar transa\u00e7\u00f5es, submeter e validar blocos, e fornecia uma API para acesso aos dados. Como o NodeJS \u00e9 originalmente de thread \u00fanica, uma pesada fun\u00e7\u00e3o de c\u00e1lculo da \u00e1rvore Merkle bloqueava a fun\u00e7\u00e3o de adi\u00e7\u00e3o de transa\u00e7\u00f5es. N\u00f3s v\u00edamos duas op\u00e7\u00f5es para resolver esse problema:<\/p>\n<p><b>1. <\/b>Executar v\u00e1rios processos NodeJS, cada um realizando fun\u00e7\u00f5es espec\u00edficas.<\/p>\n<p><b>2. <\/b>Utilizar worker_threads e mover parte do c\u00f3digo para threads.<\/p>\n<p>No final, usamos ambas as op\u00e7\u00f5es simultaneamente: dividimos logicamente um n\u00f3 em 3 partes, que podem funcionar separadamente, mas ao mesmo tempo de maneira s\u00edncrona.<\/p>\n<p><b>1.<\/b> Um n\u00f3 de submiss\u00e3o que aceita transa\u00e7\u00f5es em um pool e se encarrega da cria\u00e7\u00e3o de blocos.<\/p>\n<p><b>2.<\/b> Um n\u00f3 de valida\u00e7\u00e3o que verifica a validade dos n\u00f3s.<\/p>\n<p><b>3. <\/b>Um n\u00f3 de API \u2014 fornece uma API para acesso aos dados.<\/p>\n<p>Al\u00e9m disso, cada n\u00f3 pode ser conectado atrav\u00e9s de um socket unix utilizando cli.<\/p>\n<p>Opera\u00e7\u00f5es pesadas, como o c\u00e1lculo da \u00e1rvore Merkle, foram movidas para uma thread separada.<\/p>\n<p>Dessa forma, conseguimos fazer todas as fun\u00e7\u00f5es do Plasma Cash funcionarem simultaneamente e sem falhas.<\/p>\n<p>Assim que o sistema come\u00e7ou a operar funcionalmente, come\u00e7amos a testar a velocidade e, infelizmente, obtivemos resultados insatisfat\u00f3rios: 5.000 transa\u00e7\u00f5es por segundo e at\u00e9 50.000 transa\u00e7\u00f5es por bloco. Tivemos que investigar o que foi implementado incorretamente.<\/p>\n<p>Para come\u00e7ar, come\u00e7amos a testar o mecanismo de comunica\u00e7\u00e3o com o Plasma Cash, para saber a capacidade m\u00e1xima do sistema. Anteriormente dissemos que o n\u00f3 Plasma Cash fornece uma interface de socket unix. Originalmente, era textual. Objetos json eram transmitidos usando `JSON.parse()` e `JSON.stringify()`. <\/p>\n<pre><code class=\"plaintext\">{\"action\": \"sendTransaction\",\"payload\":{\"prevHash\": \"0x8a88cc4217745fd0b4eb161f6923235da10593be66b841d47da86b9cd95d93e0\",\"prevBlock\": 41,\"tokenId\": \"57570139642005649136210751546585740989890521125187435281313126554130572876445\",\"newOwner\": \"0x200eabe5b26e547446ae5821622892291632d4f4\",\"type\": \"pay\",\"data\": \"\",\"signature\": \"0xd1107d0c6df15e01e168e631a386363c72206cb75b233f8f3cf883134854967e1cd9b3306cc5c0ce58f0a7397ae9b2487501b56695fe3a3c90ec0f61c7ea4a721c\"}}\n<\/code><\/pre>\n<p>\nN\u00f3s medimos a velocidade de envio desses objetos e obtivemos cerca de 130k por segundo. Tentamos substituir as fun\u00e7\u00f5es padr\u00e3o de trabalho com json, mas a performance n\u00e3o melhorou. Deve ser que o motor V8 est\u00e1 bem otimizado para essas opera\u00e7\u00f5es.<\/p>\n<p>O trabalho com transa\u00e7\u00f5es, tokens e blocos foi realizado atrav\u00e9s de classes. Ao criar essas classes, o desempenho caiu pela metade, o que indica que a OOP n\u00e3o \u00e9 adequada para n\u00f3s. Tivemos que reescrever tudo usando uma abordagem puramente funcional.<\/p>\n<h2>Grava\u00e7\u00e3o no banco de dados<\/h2>\n<p>\nInicialmente, escolhemos o Redis para armazenamento de dados como uma das solu\u00e7\u00f5es mais eficientes que atende nossas demandas: um armazenamento key-value, com suporte a hash-tabelas e conjuntos. Rodamos o redis-benchmark e obtivemos cerca de 80 mil opera\u00e7\u00f5es por segundo em modo de 1 pipelining.<\/p>\n<p>Para alta performance, configuramos o Redis com mais detalhes: <\/p>\n<ul>\n<li>Estabelecemos a conex\u00e3o via unix socket.<\/li>\n<li>Desativamos o salvamento de dados no disco (para maior confiabilidade, \u00e9 poss\u00edvel configurar uma r\u00e9plica e realizar o salvamento em um Redis separado).<\/li>\n<\/ul>\n<p>\nNo Redis, um pool \u00e9 uma hash-table, pois precisamos da capacidade de obter todas as transa\u00e7\u00f5es em uma \u00fanica consulta e remover transa\u00e7\u00f5es individualmente. Tentamos usar uma lista comum, mas esta funcionou mais lentamente ao descarregar a lista inteira. <\/p>\n<p>Ao usar a biblioteca padr\u00e3o do NodeJS para Redis, obtivemos uma performance de 18 mil transa\u00e7\u00f5es por segundo. A velocidade caiu em 9 vezes. <\/p>\n<p>Como o benchmark mostrou que nossas capacidades eram claramente 5 vezes maiores, come\u00e7amos a otimizar. Mudamos a biblioteca para ioredis e conseguimos 25 mil por segundo. Adicionamos transa\u00e7\u00f5es individualmente, utilizando o comando `hset`. Assim, geramos muitas consultas no Redis. Surgiu a ideia de agrupar transa\u00e7\u00f5es em lotes e envi\u00e1-las com um \u00fanico comando `hmset`. O resultado \u2014 32 mil por segundo. <\/p>\n<p>Por v\u00e1rias raz\u00f5es, que descreveremos abaixo, trabalhamos com dados usando `Buffer` e, como se descobriu, se o convertermos em texto (`buffer.toString('hex')`) antes da grava\u00e7\u00e3o, podemos obter um desempenho adicional. Assim, a velocidade conseguiu ser aumentada para 35k por segundo. No momento, decidimos suspender a otimiza\u00e7\u00e3o adicional.<\/p>\n<p>Tivemos que mudar para um protocolo bin\u00e1rio porque:<\/p>\n<p><b>1. <\/b>O sistema frequentemente calcula hashes, assinaturas, etc., e para isso ele precisa de dados em `Buffer`.<\/p>\n<p><b>2.<\/b> Ao transmitir entre servi\u00e7os, dados bin\u00e1rios ocupam menos espa\u00e7o do que texto. Por exemplo, ao enviar um bloco com 1 milh\u00e3o de transa\u00e7\u00f5es, os dados em texto podem ocupar mais de 300 megabytes.<\/p>\n<p><b>3.<\/b> A convers\u00e3o constante de dados impacta o desempenho.<\/p>\n<p>Portanto, baseamos nosso protocolo bin\u00e1rio pr\u00f3prio de armazenamento e transmiss\u00e3o de dados, desenvolvido com a maravilhosa biblioteca `binary-data`.<\/p>\n<p>Como resultado, obtivemos as seguintes estruturas de dados:<\/p>\n<h3> \u2014 Transa\u00e7\u00e3o<\/h3>\n<p><\/p>\n<pre><code class=\"plaintext\">  ```json\n  {\n    prevHash: BD.types.buffer(20),\n    prevBlock: BD.types.uint24le,\n    tokenId: BD.types.string(null),\n    type: BD.types.uint8,\n    newOwner: BD.types.buffer(20),\n    dataLength: BD.types.uint24le,\n    data: BD.types.buffer(({current}) =&gt; current.dataLength),\n    signature: BD.types.buffer(65),\n    hash: BD.types.buffer(32),\n    blockNumber: BD.types.uint24le,\n    timestamp: BD.types.uint48le,\n  }\n  ```\n<\/code><\/pre>\n<p><\/p>\n<h3> \u2014 Token<\/h3>\n<p><\/p>\n<pre><code class=\"plaintext\">  ```json\n  {\n    id: BD.types.string(null),\n    owner: BD.types.buffer(20),\n    block: BD.types.uint24le,\n    amount: BD.types.string(null),\n  }\n  ```\n<\/code><\/pre>\n<p><\/p>\n<h3> \u2014 Bloco<\/h3>\n<p><\/p>\n<pre><code class=\"plaintext\">  ```json\n  {\n    number: BD.types.uint24le,\n    merkleRootHash: BD.types.buffer(32),\n    signature: BD.types.buffer(65),\n    countTx: BD.types.uint24le,\n    transactions: BD.types.array(Transaction.Protocol, ({current}) =&gt; current.countTx),\n    timestamp: BD.types.uint48le,\n  }\n  ```\n<\/code><\/pre>\n<p>\nUsando os comandos `BD.encode(block, Protocol).slice();` e ` BD.decode(buffer, Protocol)`, transformamos os dados em `Buffer` para armazenamento no Redis ou envio para outro n\u00f3 e extra\u00edmos os dados de volta.<\/p>\n<p>Tamb\u00e9m temos 2 protocolos bin\u00e1rios para transmiss\u00e3o de dados entre servi\u00e7os:<\/p>\n<p><i> \u2014 Protocolo para intera\u00e7\u00e3o com o Plasma Node atrav\u00e9s de socket unix<\/i><\/p>\n<pre><code class=\"plaintext\">  ```json\n  {\n    type: BD.types.uint8,\n    messageId: BD.types.uint24le,\n    error: BD.types.uint8,\n    length: BD.types.uint24le,\n    payload: BD.types.buffer(({node}) =&gt; node.length)\n  }\n  ```\n<\/code><\/pre>\n<p>\n onde:<\/p>\n<ul>\n<li> <b>`type`<\/b> \u2014 a\u00e7\u00e3o que deve ser executada, por exemplo, 1 \u2014 sendTransaction, 2 \u2014 getTransaction;<\/li>\n<li> <b>`payload`<\/b> \u2014 dados que devem ser enviados para a fun\u00e7\u00e3o correspondente;<\/li>\n<li> <b>`messageId`<\/b> \u2014 id da mensagem, para que seja poss\u00edvel identificar a resposta. <\/li>\n<\/ul>\n<p>\n<i> \u2014 Protocolo de intera\u00e7\u00e3o entre n\u00f3s<\/i><\/p>\n<pre><code class=\"plaintext\">  ```json\n  {\n    code: BD.types.uint8,\n    versionProtocol: BD.types.uint24le,\n    seq: BD.types.uint8,\n    countChunk: BD.types.uint24le,\n    chunkNumber: BD.types.uint24le,\n    length: BD.types.uint24le,\n    payload: BD.types.buffer(({node}) =&gt; node.length)\n  }\n  ```\n<\/code><\/pre>\n<p>\n onde:<\/p>\n<ul>\n<li> <b>`code`<\/b> \u2014 c\u00f3digo da mensagem, por exemplo, 6 \u2014 PREPARE_NEW_BLOCK, 7 \u2014 BLOCK_VALID, 8 \u2014 BLOCK_COMMIT;<\/li>\n<li> <b>`versionProtocol`<\/b> \u2014 vers\u00e3o do protocolo, j\u00e1 que na rede podem haver n\u00f3s com diferentes vers\u00f5es e eles podem funcionar de maneiras diferentes;<\/li>\n<li> <b>`seq`<\/b> \u2014 identificador da mensagem;<\/li>\n<li> <b>`countChunk`<\/b> e <b>`chunkNumber`<\/b> necess\u00e1rios para fragmentar mensagens grandes;<\/li>\n<li> <b>`length`<\/b> e <b>`payload`<\/b> tamanho e os pr\u00f3prios dados.<\/li>\n<\/ul>\n<p>\nComo tipificamos os dados antecipadamente, o sistema final funciona muito mais r\u00e1pido do que a biblioteca `rlp` da Ethereum. Infelizmente, ainda n\u00e3o conseguimos nos livrar dela, pois \u00e9 necess\u00e1rio aprimorar o contrato inteligente, o que planejamos fazer no futuro.<\/p>\n<p>Se conseguimos alcan\u00e7ar a velocidade <b>35 000<\/b> transa\u00e7\u00f5es por segundo, tamb\u00e9m precisamos process\u00e1-las em um tempo otimizado. Como o tempo aproximado para a forma\u00e7\u00e3o de um bloco \u00e9 de 30 segundos, precisamos incluir no bloco <b>1 000 000<\/b> transa\u00e7\u00f5es, o que significa o envio de mais de <b>100<\/b> MB de dados. <\/p>\n<p>Inicialmente, utilizamos a biblioteca `ethereumjs-devp2p` para a comunica\u00e7\u00e3o entre n\u00f3s, mas ela n\u00e3o conseguiu lidar com essa quantidade de dados. Como resultado, usamos a biblioteca `ws` e configuramos o envio de dados bin\u00e1rios por meio de websocket. Claro que tamb\u00e9m enfrentamos problemas ao enviar grandes pacotes de dados, mas dividimos esses pacotes em chunks e agora esses problemas n\u00e3o existem mais.<\/p>\n<p>A forma\u00e7\u00e3o da \u00e1rvore de Merkle e o c\u00e1lculo do hash <b>1 000 000<\/b> das transa\u00e7\u00f5es leva cerca de<b> 10<\/b> segundos de c\u00e1lculo cont\u00ednuo. Nesse tempo, a conex\u00e3o com todos os n\u00f3s acaba se desconectando. Decidimos mover esse c\u00e1lculo para uma thread separada.<\/p>\n<h2>Conclus\u00f5es:<\/h2>\n<p>\nNa verdade, nossas conclus\u00f5es n\u00e3o s\u00e3o novas, mas por algum motivo muitos especialistas as esquecem ao desenvolver. <\/p>\n<ul>\n<li>O uso de Programa\u00e7\u00e3o Funcional em vez de Programa\u00e7\u00e3o Orientada a Objetos aumenta a performance.<\/li>\n<li>Um monolito \u00e9 pior do que uma arquitetura de servi\u00e7os para um sistema produtivo em NodeJS.<\/li>\n<li>O uso de `worker_threads` para c\u00e1lculos pesados melhora a responsividade do sistema, especialmente ao lidar com opera\u00e7\u00f5es de I\/O.<\/li>\n<li>socket unix \u00e9 mais est\u00e1vel e mais r\u00e1pido do que requisi\u00e7\u00f5es http.<\/li>\n<li>Se voc\u00ea precisa transmitir grandes dados rapidamente pela rede, \u00e9 melhor usar websockets e enviar dados bin\u00e1rios, divididos em chunks, que podem ser retransmitidos se n\u00e3o chegarem, e depois reunidos em uma \u00fanica mensagem.<\/li>\n<\/ul>\n<p>\nConvidamos voc\u00ea a visitar <b>GitHub<\/b> do projeto: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opporty-com\/Plasma-Cash\/tree\/new-version\">https:\/\/github.com\/opporty-com\/Plasma-Cash\/tree\/new-version<\/a><\/noindex><\/p>\n<p>O artigo foi escrito em coautoria com <i>Alexander Nashivan<\/i>, desenvolvedor s\u00eanior <noindex><a rel=\"nofollow\" href=\"https:\/\/clever-solution.com\/\">Clever Solution Inc<\/a><\/noindex>.<br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/471096\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u2014 \u0438\u043d\u043d\u043e\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f, \u043e\u0431\u0435\u0449\u0430\u044e\u0449\u0430\u044f \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u0441\u0444\u0435\u0440\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u0439 \u0436\u0438\u0437\u043d\u0438. \u041e\u043d\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0432 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0438\u0445 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 DAPP \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u0432 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u044f\u0445. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043c\u043d\u043e\u0433\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0438 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0444\u0435\u0440\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0447\u0435\u0439\u043d, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c, \u0447\u0442\u043e \u044d\u0442\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":29146,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38856","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u2014 \u0438\u043d\u043d\u043e\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f, \u043e\u0431\u0435\u0449\u0430\u044e\u0449\u0430\u044f \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u0441\u0444\u0435\u0440\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u0439 \u0436\u0438\u0437\u043d\u0438.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0442\u0435\u0441\u0442: \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u0438 \u0432 \u042d\u0444\u0438\u0440\u0438\u0443\u043c\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u2014 \u0438\u043d\u043d\u043e\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f, \u043e\u0431\u0435\u0449\u0430\u044e\u0449\u0430\u044f \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u0441\u0444\u0435\u0440\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u0439 \u0436\u0438\u0437\u043d\u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:26:22+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:26:22+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Testemunho P\u00fablico: solu\u00e7\u00e3o para privacidade e escalabilidade no Ethereum | ProHoster","description":"Blockchain \u00e9 uma tecnologia inovadora que promete melhorar muitas \u00e1reas da vida humana.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0442\u0435\u0441\u0442: \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u0438 \u0432 \u042d\u0444\u0438\u0440\u0438\u0443\u043c\u0435 | ProHoster","og:description":"\u0411\u043b\u043e\u043a\u0447\u0435\u0439\u043d \u2014 \u0438\u043d\u043d\u043e\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f, \u043e\u0431\u0435\u0449\u0430\u044e\u0449\u0430\u044f \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u0441\u0444\u0435\u0440\u044b \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u043e\u0439 \u0436\u0438\u0437\u043d\u0438.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/publichnyj-test-reshenie-dlya-privatnosti-i-masshtabiruemosti-v-efiriume","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:26:22+00:00","article:modified_time":"2019-10-31T19:26:22+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38856","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 23:42:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:15:36","updated":"2026-01-23 23:42:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/38856","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=38856"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/38856\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/29146"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=38856"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=38856"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=38856"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}