Mas onde você armazena o conteúdo do seu aplicativo?
Imagens? Vídeos? O
front-end
do
site
do aplicativo, composto por todos os arquivos HTML, CSS e JS? Seu aplicativo e o conteúdo de seus usuários são carregados de um servidor centralizado da AWS?
Armazenar o conteúdo na
blockchain
seria caro e ineficiente.
Seu aplicativo
blockchain
precisa de armazenamento descentralizado!
Neste tutorial, apresentarei o
InterPlanetary File System
, ou IPFS. Você vai aprender:
Como armazenar e recuperar conteúdo de um armazenamento descentralizado
Como executar seu nó IPFS
Tudo sobre os componentes internos de baixo nível do protocolo IPFS
E vamos ler um
site
da Wikipédia armazenado em IPFS
Preparado? Vamos lá.
Sumário
O que é o IPFS?
Como configurar um nó IPFS
Como armazenar e recuperar conteúdo IPFS usando CLI e HTTP
O que é CID – o identificador baseado em conteúdo IPFS
Como fazer engenharia reversa do armazenamento de dados IPFS
Como conectar um nó IPFS a uma rede descentralizada
Como trocar dados usando o protocolo Bitswap ponto a ponto
Como persistir com um conteúdo acessado na rede ponto a ponto
O que é o IPFS?
O
InterPlanetary File System
, ou IPFS abreviado, é um protocolo de hipermídia ponto a ponto projetado para tornar a
web
mais rápida, segura e aberta.
IPFS é um protocolo para armazenamento e compartilhamento de conteúdo.
Como no mundo
blockchain
, cada usuário está executando seu nó (servidor). Os nós podem se comunicar entre si e trocar arquivos.
O que é único sobre o IPFS?
Em primeiro lugar, o
IPFS é descentralizado
porque carrega o conteúdo de milhares de pares em vez de um servidor centralizado. Um
hash
criptográfico é feito com cada pedaço dos dados, resultando em um
identificador de conteúdo
único e seguro: CID.
Armazene seu
site
em IPFS para evitar censura e um ponto único de falha. Seu nó IPFS pessoal fica
offline
? Não se preocupe, o
site
ainda será carregado de outros nós que o atendem globalmente.
Por exemplo, suponha que seu governo proíba a Wikipédia. Nesse caso, você ainda pode acessar uma versão descentralizada da Wikipédia indexada em 17 de abril, carregando-a da rede ponto a ponto IPFS persistida sob o CID:
"
QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX"
Em segundo lugar, a integridade do
conteúdo IPFS pode ser verificada criptograficamente
.
E, finalmente,
o conteúdo IPFS é desduplicado
. Se você tentasse armazenar dois arquivos idênticos de 1 MB no mesmo nó IPFS, eles seriam armazenados apenas uma vez, eliminando a duplicação, pois seu
hash
produziria um
CID
idêntico.
Como Configurar um Nó IPFS
Compilando a base de código em Go
Clone o repositório e execute o
script
de instalação no Makefile.
git clone https://github.com/ipfs/go-ipfs.git
cd go-ipfs
git checkout v0.8.0-rc2
make installValidando a instalação
Sejamos honestos. O Go é incrível e compilar a base de código você mesmo é muito legal e descentralizado. O binário resultante será criado em seu $GOPATH.
whichipfs>/home/web3coach/go/bin/ipfsipfsversion>ipfsversion0.8.0-rc2Enter fullscreen modeExit fullscreen modeInicializando um novo nó
Execute ipfs init para criar seu novo nó. Por padrão, ele criará uma pasta e armazenará todos os dados em ~/.ipfs. Você pode ajustar isso configurando a variável ENV IPFS_PATH.
Ao executar o comando add ao conteúdo, você o adiciona SOMENTE ao seu nó local. O conteúdo NÃO é replicado automaticamente em toda a rede – essa é uma confusão comum entre usuários e desenvolvedores do IPFS.
Quando você armazena conteúdo por meio do comando add, o IPFS também executa o comando pin por padrão:
ipfspinaddQmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6zEnter fullscreen modeExit fullscreen modeComo Funciona o Endereçamento de Conteúdo IPFS
O que é QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z?
É um identificador baseado em conteúdo autodescritivo.
O que "autodescritivo" realmente significa? Isso significa que, ao dividir a string seguindo a especificação IPFS, você saberá tudo o que precisa saber sobre os dados que ela indexa.
qual é a versão do CID
como ler a string do CID (base32? base58? hex?)
como os dados são codificados
qual função hash imprimiu os dados
o comprimento da função hash
A equipe do IPFS construiu um site bem conveniente para analisar um CID:
Ao analisar o CID QmRBkKi1P…p6z, você descobre:
o CID segue a especificação da versão 0 porque começa com Qm
a stringQmRBkKi1P…p6z é codificada usando base58btc
os dados "hello IPFS world by Web3Coach. BTW: Ethereum FTW" foram codificados como DAG (Directed Acyclic Graph, ou Grafo Acíclico Dirigido) Protobuf (Protocol Buffer) sob um codec0x70 antes de serem armazenados em disco
o código hash0x12 sinaliza a impressão digital de dados obtida usando a função hashsha256, produzindo um resumo único de 32 bytes
"Um pouco mais complicado" do que um simples incremento automático INT em uma tabela MySQL... mas extraordinariamente potente e à prova de futuro. Deixe-me explicar.
Versões CID
Existem atualmente duas versões de CID: v0 e v1.
O CID v0 não é flexível e limitado a:
começar com os caracteres "Qm"
onde a string CID é codificada usando base58btc
os dados são codificados com DAG Protobuf por padrão
pode ser convertido para CID versão 1, mas não o contrário
O CID v1 aproveita vários prefixos para máxima interoperabilidade:
CID v1 = Multibase + Multicodec + Multihash
Em outras palavras, analisar o binário em uma string CID v1 segue esta especificação:
<base><codec><hash-function><hash-length><hash-digest>
Enter fullscreen modeExit fullscreen modeMultihash
Para ser à prova de futuro e permitir diferentes algoritmos de hash, o IPFS criou o seguinte padrão:
O atributo Code informa como os dados são codificados antes de serem armazenados no disco, para que você saiba como decodificá-los de volta quando o usuário quiser lê-los. Pode-se usar qualquer um, como CBOR, Protobuf, JSON…
O IPFS mantém uma lista pública de todos os codecs possíveis. Os codecs mais comuns são:
raw | ipld | 0x55 | raw binary
dag-pb | ipld | 0x70 | MerkleDAG protobuf
dag-cbor | ipld | 0x71 | MerkleDAG cbor
// mas você também pode codificar blocos Ethereum no IPFS!
eth-block | ipld | 0x90 | Ethereum Block (RLP)
Enter fullscreen modeExit fullscreen modeMultibase
O problema com o CID v0 e a codificação base58btc é a falta de interoperabilidade entre os ambientes. Um prefixo multibase adiciona suporte para diferentes codificações, como base32, para obter nomes compatíveis com DNS.
Ambas as versões do CID podem recuperar o mesmo conteúdo porque depois que você remove a codificação, é o Multihash que indexa os blocos no nível do armazenamento de dados. Por outro lado, o Multibase é usado apenas para passar o CID corretamente em diferentes ambientes (CLI, URL, DNS).
Ufa. As coisas ficaram "ligeiramente complexas" muito rapidamente.
Falando de tópicos complicados, o IPFS é poderoso porque não trata o conteúdo apenas como "dados", mas como estruturas de dados – especificamente a estrutura InterPlanetary Linked Data: IPLD. Em resumo, você pode implementar qualquer sistema de arquivos, banco de dados ou estrutura em cima do IPLD.
Por exemplo, você pode armazenar todos os blocos Ethereum no IPFS contanto que você defina os codecseth-block e eth-tx e registre um decodificador apropriado ao trabalhar com o IPLD.
Vamos nos aprofundar e explorar a estrutura padrão do IPLD com o codec DAG Protobuf.
Como o IPFS armazena conteúdo no Sistema de Arquivos
“O comando ipfs add criará uma estrutura Merkle DAG à partir dos dados seguindo o formato de dados UnixFS. Seu conteúdo é dividido em blocos usando um Chunker (“picador” de dados) e, em seguida, organizado em uma estrutura semelhante a uma árvore (Árvore de Merkle) usando 'nós de links' para juntá-los. O CID retornado é o hash do nó raiz no DAG.”
Confuso?
Voltando ao básico.
Vamos explorar o diretório de dados do nó
No início deste tutorial, ao inicializar seu nó IPFS com o comando ipfs init, você gerou o seguinte diretório:
export IPFS_PATH=/home/web3coach/.ipfs_tutorial
cd$IPFS_PATH
~/.ipfs_tutorial tree
├── blocks
│ ├── 6Y
│ │ └── CIQA4XCGRCRTCCHV7XSGAZPZJOAOHLPOI6IQR3H6YQ.data
├── config
├── datastore
│ ├── 000002.ldb
│ ├── 000003.log
│ ├── CURRENT
│ ├── CURRENT.bak
│ ├── LOCK
│ ├── LOG
│ └── MANIFEST-000004
├── datastore_spec
├── keystore
└── version
Enter fullscreen modeExit fullscreen modeblocks - O IPFS armazena todos os pedaços de dados aqui, embora as interfaces flexíveis go-ipfspermitam que você troque a implementação de armazenamento por um banco de dados diferente
config - Configurações do nó (sistema de arquivos, identidade, especificações, rede)
datastore - Indexação e outras lógicas
Não confie no que eu digo. Crie você mesmo um novo arquivo com o seguinte conteúdo em seu sistema de arquivos local e adicione-o ao IPFS:
helloIPFSworldbyWeb3Coach.TestingDAGshelloIPFSworldbyWeb3Coach.TestingDAGshelloIPFSworldbyWeb3Coach.TestingDAGsls-lahello_world.txt>131byteshello_world.txtipfsaddhello_world.txt>addedQmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtHEnter fullscreen modeExit fullscreen mode
IPFS UnixFS - Adicionando um novo arquivo e convertendo-o em um bloco
Valide o processo de persistência inspecionando o diretório de blocos. Você descobrirá que o conteúdo foi escrito sob a chave Multihash Datastore Key usando a codificação DAG Protobuf (131 bytes + codificação extra Protobuf).
ls-lablocks/PV/>142CIQAQIXXW2OAQSKZ6AQ2SDEYRZXWPDZNJUAFR3YORYN75I5CQ3LHPVQ.datavimblocks/PV/CIQA...<8b>^A^H^B^R<83>^AhelloIPFSworldbyWeb3Coach.TestingDAGshelloIPFSworldbyWeb3Coach.TestingDAGshelloIPFSworldbyWeb3Coach.TestingDAGs^X<83>^AEnter fullscreen modeExit fullscreen mode"Links":[],"Data":"\b\u0002\u0012'\u0001hello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing DAGs\u0018'\u0001"Enter fullscreen modeExit fullscreen mode
Como o conteúdo é de apenas 131 bytes, cabe em um nó DAG
O nó DAG é persistido como um bloco no disco
O nó DAG tem zero links para outros nós
Hora de experimentar.
Adicione o mesmo arquivo novamente, mas configure o Chunker para 64 bytes (ou use um arquivo maior, mas um Chunker menor demonstrará melhor o conceito).
ipfsadd--chunker=size-64hello_world.txt>131bytesQmTwtTQgrTaait2qWXYjTsEZiF4sT7CD4U87VqQ27Wnsn8Enter fullscreen modeExit fullscreen mode"Links":[],"Data":"\b\u0002\u0012@hello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by \u0018@"Enter fullscreen modeExit fullscreen mode"Links":[],"Data":"\b\u0002\u0012@Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing D\u0018@"Enter fullscreen modeExit fullscreen modeQual é o benefício de dividir o conteúdo em vários pedaços e usar endereçamento de conteúdo e CIDs?
Desduplicação de dados
Descentralização
Se você eventualmente quisesse armazenar um arquivo que compartilhasse parte de seu conteúdo com outro arquivo, o IPFS não armazenaria um bloco duplicado! Em vez disso, ele se vincularia a um nó DAG já existente e armazenaria apenas os pedaços novos e únicos.
Converter o conteúdo em um grafo acíclico dirigido (DAG) com muitos nós também ajuda a carregar o conteúdo em paralelo. Por exemplo: uma postagem de um blog, uma imagem e o site inteiro da Wikipédia podem ser carregados de vários nós de pares IPFS. Seu nó então verifica a integridade dos blocos recebidos refazendo o hash de todo o conteúdo de dados e afirmando o CID construído.
Agora você aprendeu o pão com manteiga do IPFS – excelente progresso!
Falta mais um componente crítico: a Rede.
Como conectar um nó IPFS à rede p2p
Cada nó tem seu arquivo config gerado durante a execução do ipfs init.
Você se conecta a outros pares na rede IPFS executando o comando ipfs daemon. Seu nó primeiro estabelecerá uma conexão p2p com nós de inicialização da Protocol Labs (empresa por trás do IPFS) e, por meio desses nós de inicialização, você encontrará centenas de outros pares.
Seu nó se conecta à rede p2p e pode trocar blocos com outros nósOutros pares podem acessar o conteúdo em seu nó – desde que conheçam os CIDs
Os pares se comunicarão com você através de TCP, UDP na porta: 4001
Se você tiver um aplicativo, comece a armazenar e consumir o conteúdo do seu nó por meio da API HTTP acessando a porta: 5001.
Para desenvolvimento de aplicações, recomendo a biblioteca oficial ipfs-http-client em JS expondo todos os comandos principais – add, cat, object e outros. Isso acelerará seu progresso de codificação.
Usarei curl para interagir com a API para manter este tutorial "curto".
curl-XPOST"http://127.0.0.1:5001/api/v0/cat?arg=QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH"helloIPFSworldbyWeb3Coach.TestingDAGshelloIPFSworldbyWeb3Coach.TestingDAGshelloIPFSworldbyWeb3Coach.TestingDAGsEnter fullscreen modeExit fullscreen modeComo fazer pareamento com outros nós IPFS
Experiência divertida. Use o comando ipfs swarm e verifique quantos nós você já descobriu:
ipfsswarmpeers/ip4/85.70.151.37/tcp/4001/p2p/QmSuCtR...aPq6h4AczBPZaoej/ip4/91.121.168.96/udp/54001/quic/p2p/QmeC7H...8j2TQ99esSipfsswarmpeers|wc-lEnter fullscreen modeExit fullscreen modeComo os nós trocam dados usando o protocolo Bitswap
Até agora, você só interagiu com seu conteúdo local. Imagine que você mora em um lugar onde o governo local decidiu bloquear o acesso à Wikipédia. Isso não é bom.
Felizmente, como alguém adicionou todo o conteúdo da Wikipédia ao IPFS, você pode executar seu nó e acessar seu conhecimento solicitando o conteúdo de pares em todo o mundo.
O serviço DAG verificará os blocos em seu armazenamento de dados, mas não encontrará nenhum para QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX.
O nó, portanto, criará uma solicitação de rede para seus pares usando o protocolo Bitswap via o componente exchange:
funcgetBlock(ctxcontext.Context,ccid.Cid,bsblockstore.Blockstore,fgetfunc()exchange.Fetcher)(blocks.Block,error){err:=verifcid.ValidateCid(c)// segurança do hashiferr!=nil{returnnil,errblock,err:=bs.Get(c)iferr==nil{returnblock,niliferr==blockstore.ErrNotFound&&fget!=nil{f:=fget()// Não carregue o comando exchange até que tenhamos que carregá-lolog.Debug("Blockservice: Searching bitswap")blk,err:=f.GetBlock(ctx,c)Enter fullscreen modeExit fullscreen mode
// Wantlist é uma lista bruta de blocos desejados e suas prioridadestypeWantliststruct{setmap[cid.Cid]Entry// Entry é uma entrada em uma lista de desejos, consistindo em um cid e sua prioridadetypeEntrystruct{Cidcid.CidPriorityint32WantTypepb.Message_Wantlist_WantTypeEnter fullscreen modeExit fullscreen mode
E o PeerManager irá iterar sobre pares conhecidos e seus respectivos pares até encontrar um nó online capaz de fornecer o Bloco desejado:
// O PeerManager gerencia um pool de pares e envia mensagens para pares no pool.typePeerManagerstruct{pqLksync.RWMutexpeerQueuesmap[peer.ID]PeerQueuepwm*peerWantManagercreatePeerQueuePeerQueueFactoryctxcontext.ContextpsLksync.RWMutexsessionsmap[uint64]SessionpeerSessionsmap[peer.ID]map[uint64]struct{}selfpeer.IDEnter fullscreen modeExit fullscreen modeFixação e Coleta do Lixo
No início do artigo, você aprendeu que o conteúdo adicionado ao seu nó por meio do comando ipfs add ou seu equivalente HTTP é fixado por padrão.
Os blocos fixados são marcados como NÃO EXCLUIR quando a Coleta do Lixo é executada.
Por que a Coleta do Lixo excluiria alguns blocos? Para manter seu nó íntegro, controlando seu tamanho de armazenamento.
Lendo a Wikipédia ou acessando qualquer outro conteúdo da rede p2p, o IPFS baixa seus blocos. À medida que o armazenamento de dados do nó aumenta de tamanho, um processo periódico de coleta de lixo removerá os blocos não fixados, para que você não fique sem espaço em disco.
Se você deseja que seu conteúdo seja acessível 24 horas por dia, 7 dias por semana na rede IPFS, recomendo que você use um provedor remoto confiável para fixá-lo: Infura - é a maneira mais fácil de começar e você obtém gratuitamente 5 GB de armazenamento descentralizado.
O objeto DAG raiz tem cinco links. Quatro links são relativamente pequenos, mas um linkaponta para um nó DAG com um tamanho total de 12 GB. Se você inspecionar esse nó DAG, verá mais 256 links e um tamanho total acumulativo (recursivo) de 12 GB.
O processo de fixação percorrerá recursivamente todo o nó DAG, buscará todos os seus links do protocolo Bitswap e, em seguida, fixará cada bloco em seu armazenamento de dados local.
Parabéns! Neste artigo, você aprendeu como o armazenamento descentralizado funciona nos bastidores.
Trabalhei 47 horas para escrever esta postagem no blog… mas você pode compartilhar no Twitter em apenas 5 segundos:
Ex-engenheiro de software do trivago, autor e instrutor de blockchain. Eu treino desenvolvedores de software para a nova era da Web3 ensinando como construir sistemas blockchain e aplicativos Ethereum.
Aprenda a codificar gratuitamente. O currículo de código aberto do freeCodeCamp ajudou mais de 40.000 pessoas a conseguir empregos como desenvolvedores. Comece aqui.
Artigo publicado por Lukas Lukac em 21 de junho de 2021, traduzido por Paulinho Giovannini. Você pode encontrar a publicação original aqui.
Sharding: Uma Solução Interessante para Melhorar a Escalabilidade da Blockchain
#sharding#fragmentacao#blockchain#escalabilidade
Como Iniciar uma DAO
#dao#framework#descentralizacao#blockchain
Cross-Chain Interoperability Protocol (CCIP): Desbloqueando a Interoperabilidade entre Blockchains
#ccip#chainlink#blockchain#interoperabilidade
Once unpublished, all posts by paulogio will become hidden and only accessible to themselves.
If paulogio is not suspended, they can still re-publish their posts from their dashboard.