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:
- 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
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.
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
Ou baixe o IPFS pré-compilado:
sudo snap install ipfs
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
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
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
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%
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
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
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>
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
}
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)
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
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
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
De um ponto de vista de alto nível:
-
blocks
- O IPFS armazena todos os pedaços de dados aqui, embora as interfaces flexíveisgo-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
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
Para interagir com seu conteúdo bruto, use o comando ipfs object
.
ipfs object get QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH | jq
{
"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"
}
- 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
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
{
"Links": [
{
"Name": "",
"Hash": "QmTbsuUYzy3nT6NApb5t7VUq3iQKZXrJJJY2j1miMVgaJU",
"Size": 72
},
{
"Name": "",
"Hash": "QmNy9iFF8uU1Cn7trxpSgqxMsjmi4zQ7xgyEgsWff5rnfH",
"Size": 72
},
{
"Name": "",
"Hash": "QmdEitCfYgBNxLhxTNvdLaDmTypSAWkGErjw33VZxUbWK3",
"Size": 11
}
],
"Data": "\b\u0002\u0018'\u0001 @ @ \u0003"
}
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
{
"Links": [],
"Data": "\b\u0002\u0012@hello IPFS world by Web3Coach. Testing DAGs\nhello IPFS world by \u0018@"
}
Nó 2 DAG Protobuf:
ipfs object get QmNy9iFF8uU1Cn7trxpSgqxMsjmi4zQ7xgyEgsWff5rnfH | jq
{
"Links": [],
"Data": "\b\u0002\u0012@Web3Coach. Testing DAGs\nhello IPFS world by Web3Coach. Testing D\u0018@"
}
Nó 3 DAG Protobuf:
ipfs object get QmdEitCfYgBNxLhxTNvdLaDmTypSAWkGErjw33VZxUbWK3 | jq
{
"Links": [],
"Data": "\b\u0002\u0012\u0003AGs\u0018\u0003"
}
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
Outras configurações à parte, você encontra a identidade do seu nó (PeerID + chave privada):
"Identity": {
"PeerID": "12D3KooWCBmDtsvFwDHEr...",
"PrivKey": "CAESQCj..."
},
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"
],
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!
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"
{"Name":"hello_world.txt","Hash":"QmNtQtxeavDXTjCiWAAaxnhKK3LBYfFfpXUXjdMDYXwKtH","Size":"142"}
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
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
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)
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
}
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
}
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
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
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
{
"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"
}
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
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
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:
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.
Oldest comments (0)