WEB3DEV

Cover image for Um Guia Técnico para o IPFS - O Armazenamento Descentralizado da Web3
Paulo Gio
Paulo Gio

Posted on • Atualizado em

Um Guia Técnico para o IPFS - O Armazenamento Descentralizado da Web3

Quando você pensa no desenvolvimento de um aplicativo descentralizado, uma blockchain como a Ethereum provavelmente vem à mente.

A Blockchain é fantástica para gerenciar o estado, automatizar processos por meio de contratos inteligentes e trocar valores econômicos.

Se quiser saber mais, siga este tutorial para aprender sobre blockchain, construindo você mesmo uma do zero.

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:

  1. Como armazenar e recuperar conteúdo de um armazenamento descentralizado
  2. Como executar seu nó IPFS
  3. Tudo sobre os componentes internos de baixo nível do protocolo IPFS
  4. 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

Instalando o IPFS

Abra a página de instalação oficial da documentação IPFS e siga as instruções dependendo do seu sistema operacional (Windows, macOS, Linux). Irei documentar o processo de instalação da versão Ubuntu abaixo.

command-line

Documentos de instalação do IPFS

Eu prefiro compilar o repositório ipfs/go-ipfs do zero para depurar o código quando necessário, e sejamos honestos: o GoLang arrasa.

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 install
Enter fullscreen mode Exit fullscreen mode

Ou baixe o IPFS pré-compilado:

sudo snap install ipfs
Enter fullscreen mode Exit fullscreen mode

Validando 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.

which ipfs
> /home/web3coach/go/bin/ipfs

ipfs version
> ipfs version 0.8.0-rc2
Enter fullscreen mode Exit fullscreen mode

Inicializando 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.

IPFS_PATH=/home/web3coach/.ipfs_tutorial ipfs init

> generating ED25519 keypair...done
> peer identity: 12D3Koo...dNs
> initializing IPFS node at /home/web3coach/.ipfs_tutorial
Enter fullscreen mode Exit fullscreen mode

Seu nó agora está totalmente inicializado, aguardando seu conteúdo.

Como usar o IPFS

Adicionando conteúdo

O IPFS pode lidar com todos os tipos de dados diferentes – desde strings simples até imagens, vídeos e sites.

Comece armazenando a curta mensagem hello IPFS world by Web3Coach:

echo "hello IPFS world by Web3Coach. BTW: Ethereum FTW" | ipfs add
Enter fullscreen mode Exit fullscreen mode

O conteúdo agora é armazenado e indexado por uma função hash criptográfica, que retorna seu identificador único de conteúdo (CID):

> added QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
> 49 B / 49 B [========] 100%
Enter fullscreen mode Exit fullscreen mode

Seu nó IPFS gerará o mesmo CID, tanto em seu sistema de arquivos local como neste tutorial. Isso ocorre porque o IPFS executa o hash do conteúdo e retorna sua impressão digital exclusiva e, como sabemos, uma função hash segura sempre retornará o mesmo output dado o mesmo input.

Fixando conteúdo

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:

ipfs pin add QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
Enter fullscreen mode Exit fullscreen mode

Para replicar o conteúdo, você deve colocar seu nó online, ingressar na rede p2p e executar o comando pin ao CID específico de outro nó. Você aprenderá como fazer isso mais adiante no tutorial e descobrirá o que acontece em segundo plano.

Lendo conteúdo

Copie e cole o CID ao comando IPFS cat para ler do disco:

ipfs cat QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
> hello IPFS world by Web3Coach. BTW: Ethereum FTW
Enter fullscreen mode Exit fullscreen mode

Os comandos add, pin e cat são as funções IPFS mais significativas, e você acabou de aprendê-las. Parabéns, muito bem feito!

Como 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 string QmRBkKi1P…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 codec 0x70 antes de serem armazenados em disco
  • o código hash 0x12 sinaliza a impressão digital de dados obtida usando a função hash sha256, 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 mode Exit fullscreen mode

Multihash

Para ser à prova de futuro e permitir diferentes algoritmos de hash, o IPFS criou o seguinte padrão:

CÓDIGO: TAMANHO: RESUMO

type DecodedMultihash struct {
   Code   uint64  // 0x12
   Name   string  // sha2-256
   Length int   // 32 bytes
   Digest []byte  // Resumo contém os bytes multihash brutos
}
Enter fullscreen mode Exit fullscreen mode

Multihash tem muitas vantagens. Quando os computadores estiverem mais poderosos em 5 anos, você poderá usar uma função hash mais forte, como sha3-512, desde que você configure o código 0x13 correspondente como o Multihash no prefixo CID – o protocolo estará pronto para lidar com isso.

Multicodec

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 mode Exit fullscreen mode

Multibase

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.

Uma tabela com todas as codificações Multibase:

encoding  | code
base32    | b
base58btc | z
base64    | m
Enter fullscreen mode Exit fullscreen mode

Você identifica uma codificação Multibase com base no primeiro caractere:

QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z

  • é CID v0
  • a string CID é codificada com base58btc

bafybeibkjmxftowv4lki46nad4arescoqc7kdzfnjkqux257i4jonk44w4

  • CID v1
  • a string CID é codificada com base32

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).

ipfs cat QmRBkKi1PnthqaBaiZnXML6fH6PNqCFdpcBxGYXoUQfp6z
> hello IPFS world by Web3Coach. BTW: Ethereum FTW

// equivalente a
ipfs cat bafybeibkjmxftowv4lki46nad4arescoqc7kdzfnjkqux257i4jonk44w4
> hello IPFS world by Web3Coach. BTW: Ethereum FTW
Enter fullscreen mode Exit fullscreen mode

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 codecs eth-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 mode Exit fullscreen mode

De um ponto de vista de alto nível:

  • blocks -  O IPFS armazena todos os pedaços de dados aqui, embora as interfaces flexíveis go-ipfs permitam 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:

hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs

ls -la hello_world.txt
> 131 bytes hello_world.txt

ipfs add hello_world.txt
> added QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH
Enter fullscreen mode Exit fullscreen mode

Fazendo a engenharia reversa da base de código go-ipfs, isso é o que está acontecendo nos bastidores:

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 -la blocks/PV/
> 142 CIQAQIXXW2OAQSKZ6AQ2SDEYRZXWPDZNJUAFR3YORYN75I5CQ3LHPVQ.data

vim blocks/PV/CIQA...
<8b>^A^H^B^R<83>^Ahello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs^X<83>^A
Enter fullscreen mode Exit fullscreen mode

Para interagir com seu conteúdo bruto, use o comando ipfs object.

ipfs object get QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH | jq
Enter fullscreen mode Exit 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 mode Exit 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).

ipfs add --chunker=size-64 hello_world.txt

> 131 bytes QmTwtTQgrTaait2qWXYjTsEZiF4sT7CD4U87VqQ27Wnsn8
Enter fullscreen mode Exit fullscreen mode

Você recebeu um novo CID!

O IPFS dividiu o conteúdo em 4 nós DAG e gravou 4 blocos com dados codificados no formato DAG Protobuf no disco.

O IPFS divide um arquivo em vários pedaços (nós DAG + blocos)
ipfs object get QmTwtTQgrTaait2qWXYjTsEZiF4sT7CD4U87VqQ27Wnsn8 | jq
Enter fullscreen mode Exit fullscreen mode
{
  "Links": [
    {
      "Name": "",
      "Hash": "QmTbsuUYzy3nT6NApb5t7VUq3iQKZXrJJJY2j1miMVgaJU",
      "Size": 72
    },
    {
      "Name": "",
      "Hash": "QmNy9iFF8uU1Cn7trxpSgqxMsjmi4zQ7xgyEgsWff5rnfH",
      "Size": 72
    },
    {
      "Name": "",
      "Hash": "QmdEitCfYgBNxLhxTNvdLaDmTypSAWkGErjw33VZxUbWK3",
      "Size": 11
    }
  ],
  "Data": "\b\u0002\u0018'\u0001 @ @ \u0003"
}
Enter fullscreen mode Exit fullscreen mode

O teste final é recuperar os dados de cada nó DAG e verificar se o texto está dividido em três partes:

Nó 1 DAG Protobuf:

ipfs object get QmTbsuUYzy3nT6NApb5t7VUq3iQKZXrJJJY2j1miMVgaJU | jq
Enter fullscreen mode Exit fullscreen mode
{
  "Links": [],
  "Data": "\b\u0002\u0012@hello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by \u0018@"
}
Enter fullscreen mode Exit fullscreen mode

Nó 2 DAG Protobuf:

ipfs object get QmNy9iFF8uU1Cn7trxpSgqxMsjmi4zQ7xgyEgsWff5rnfH | jq
Enter fullscreen mode Exit fullscreen mode
{
  "Links": [],
  "Data": "\b\u0002\u0012@Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing D\u0018@"
}
Enter fullscreen mode Exit fullscreen mode

Nó 3 DAG Protobuf:

ipfs object get QmdEitCfYgBNxLhxTNvdLaDmTypSAWkGErjw33VZxUbWK3 | jq
Enter fullscreen mode Exit fullscreen mode
{
  "Links": [],
  "Data": "\b\u0002\u0012\u0003AGs\u0018\u0003"
}
Enter fullscreen mode Exit fullscreen mode

Qual é 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.

Abra-o.

vim $IPFS_PATH/config
Enter fullscreen mode Exit fullscreen mode

Outras configurações à parte, você encontra a identidade do seu nó (PeerID + chave privada):

"Identity": {
    "PeerID": "12D3KooWCBmDtsvFwDHEr...",
    "PrivKey": "CAESQCj..."
  },
Enter fullscreen mode Exit fullscreen mode

E uma lista de endereços de inicialização (Bootstrap):

"Bootstrap": [
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59b...gU1ZjYZcYW3dwt",
    "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMG...UtfsmvsqQLuvuJ",
    "/ip4/104.131.131.82/udp/4001/quic/p2p/Qma...UtfsmvsqQLuvuJ",
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooD5...BMjTezGAJN",
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2Ec...J16u19uLTa",
    "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnM...Ucqanj75Nb"
  ],
Enter fullscreen mode Exit fullscreen mode

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.

ipfs daemon 

> Initializing daemon...

Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/127.0.0.1/udp/4001/quic
Swarm listening on /ip4/172.17.0.1/tcp/4001
Swarm listening on /ip4/172.17.0.1/udp/4001/quic
Swarm listening on /ip4/192.168.0.142/tcp/4001
Swarm listening on /ip4/192.168.0.142/udp/4001/quic
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /ip6/::1/udp/4001/quic
Swarm listening on /p2p-circuit
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip4/127.0.0.1/udp/4001/quic
Swarm announcing /ip4/192.168.0.142/tcp/4001
Swarm announcing /ip4/192.168.0.142/udp/4001/quic
Swarm announcing /ip4/88.212.40.160/udp/4001/quic
Swarm announcing /ip6/::1/tcp/4001
Swarm announcing /ip6/::1/udp/4001/quic

API server listening on /ip4/127.0.0.1/tcp/5001
WebUI: http://127.0.0.1:5001/webui

Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready!
Enter fullscreen mode Exit fullscreen mode

Tenha em mente que, executando o IPFS Daemon:

  • Seu nó se conecta à rede p2p e pode trocar blocos com outros nós
  • Outros 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".

Como usar a API HTTP IPFS:

Adicionar conteúdo: :5001/api/v0/add

curl -X POST -F file=@/home/web3coach/go/src/github.com/ipfs/go-ipfs/hello_world.txt "http://127.0.0.1:5001/api/v0/add"
Enter fullscreen mode Exit fullscreen mode
{"Name":"hello_world.txt","Hash":"QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH","Size":"142"}
Enter fullscreen mode Exit fullscreen mode

Leia o conteúdo: :5001/api/v0/cat

curl -X POST "http://127.0.0.1:5001/api/v0/cat?arg=QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH"

hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
hello IPFS world by Web3Coach. Testing DAGs
Enter fullscreen mode Exit fullscreen mode

Consulte os documentos oficiais da API HTTP para a lista completa de comandos disponíveis.

Como fazer pareamento com outros nós IPFS

Experiência divertida. Use o comando ipfs swarm e verifique quantos nós você já descobriu:

ipfs swarm peers

>
/ip4/85.70.151.37/tcp/4001/p2p/QmSuCtR...aPq6h4AczBPZaoej
/ip4/91.121.168.96/udp/54001/quic/p2p/QmeC7H...8j2TQ99esS
...
...
...

ipfs swarm peers | wc -l
> 186
Enter fullscreen mode Exit fullscreen mode

Bravo! Você está conectado a 186 pares formando uma rede ponto a ponto (p2p) imparável.

E a privacidade?

Outros pares podem acessar todo o conteúdo que você adiciona ao nó IPFS. Não há mecanismo de privacidade integrado, portanto, nunca adicione conteúdo não criptografado, sensível/pessoal ao IPFS!

Como 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.

http://localhost:8080/ipfs/QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX/wiki/Anasayfa.html

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:

func getBlock(ctx context.Context, c cid.Cid, bs blockstore.Blockstore, fget func() exchange.Fetcher) (blocks.Block, error) {
   err := verifcid.ValidateCid(c) // segurança do hash
   if err != nil {
      return nil, err
   }

   block, err := bs.Get(c)
   if err == nil {
      return block, nil
   }

   if err == blockstore.ErrNotFound && fget != nil {
      f := fget() // Não carregue o comando exchange até que tenhamos que carregá-lo

      log.Debug("Blockservice: Searching bitswap")
      blk, err := f.GetBlock(ctx, c)
Enter fullscreen mode Exit fullscreen mode

Internamente, o CID é adicionado a uma lista Wantlist:

// Wantlist é uma lista bruta de blocos desejados e suas prioridades
type Wantlist struct {
   set map[cid.Cid]Entry
}

// Entry é uma entrada em uma lista de desejos, consistindo em um cid e sua prioridade
type Entry struct {
   Cid      cid.Cid
   Priority int32
   WantType pb.Message_Wantlist_WantType
}
Enter fullscreen mode Exit 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.
type PeerManager struct {
   pqLk sync.RWMutex

   peerQueues map[peer.ID]PeerQueue
   pwm        *peerWantManager

   createPeerQueue PeerQueueFactory
   ctx             context.Context

   psLk         sync.RWMutex
   sessions     map[uint64]Session
   peerSessions map[peer.ID]map[uint64]struct{}

   self peer.ID
}
Enter fullscreen mode Exit fullscreen mode

O resultado?

Você pode consumir os frutos proibidos da Wikipédia diretamente de localhost:8080:

IPFS carregando a Wikipédia em seu nó local

Armazenamento sem censura e descentralizado :)

Como persistir com o conteúdo da rede p2p

Você já deve saber uma coisa crucial sobre o IPFS: o conteúdo que você acessa na rede será coletado como lixo, a menos que você o fixe.

Fixaçã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.

ipfs pin ls | grep QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH
> QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH recursive
Enter fullscreen mode Exit fullscreen mode

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.

Siga os documentos de introdução ao Infura.

Como fixar a Wikipédia localmente

Verifique se o CID de nível raiz da Wikipédia (nó DAG mais alto) ainda não está fixado em seu nó:

ipfs pin ls | grep QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX
> no output, not pinned
Enter fullscreen mode Exit fullscreen mode

O IPFS armazena versões específicas da Wikipédia na forma de um DAG. Eu recomendo inspecionar seu grafo antes de fixar:

ipfs object get QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX | jq
Enter fullscreen mode Exit fullscreen mode
{
  "Links": [
    {
      "Name": "0C-",
      "Hash": "QmSEwJo8Z5bqVX3AhocyimJzPWetr7HgbWbwCg6zbp43AP",
      "Size": 1248085
    },
    {
      "Name": "43I",
      "Hash": "QmPW3kRjncDj145bP9DVNc791FowLPwYHnqbTzfe3whdyZ",
      "Size": 2611324931
    },
    {
      "Name": "58wiki",
      "Hash": "QmRNXpMRzsTHdRrKvwmWisgaojGKLPqHxzQfrXdfNkettC",
      "Size": 12295304394
    },
    {
      "Name": "92M",
      "Hash": "Qmbcvk7jpBTUKdgex139Nvv7BrKocE3pQVKhNJtTU77Qv5",
      "Size": 793
    },
    {
      "Name": "A0index.html",
      "Hash": "QmNqbYogAxH4mmt5WhuKN7NFEUDZ9V3Scxh7QbLwTKBJDk",
      "Size": 191
    }
  ],
  "Data": "\b\u0005\u0012\u0015\u0001\u0000\u0004\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0000\b\u0000\u0000\u0000\u0000\u0000\u0000\u0010\u0000(\"0'\u0002"
}
Enter fullscreen mode Exit fullscreen mode

O objeto DAG raiz tem cinco links. Quatro links são relativamente pequenos, mas um link aponta 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.

ipfs object stat QmRNXpMRzsTHdRrKvwmWisgaojGKLPqHxzQfrXdfNkettC

NumLinks:       256
BlockSize:      12075
LinksSize:      12034
DataSize:       41
CumulativeSize: 12295304394
Enter fullscreen mode Exit fullscreen mode

Cada nó fixado com um importante artigo, vídeo, documentário ou um meme de gato torna a web mais acessível, antifrágil, descentralizada e robusta.

ipfs pin add QmT5NvUtoM5nWFfrQdVrFtvGfKFmG7AHE8P34isapyhCxX
Enter fullscreen mode Exit fullscreen mode

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:

Link do post no Twitter

Sobre o Autor: Lukas Lukac

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.

Se você leu até aqui, mande um tweet para o autor para mostrar que você se importa. Envie um tweet de agradecimento aqui.

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.

Top comments (0)