Guia Prático: Blockchain e Contratos Inteligentes II

Na primeira parte deste guia prático exploramos os fundamentos da blockchain. A segunda parte tem um foco claro e objetivo: mostrar na prática a estrutura dos contratos inteligentes e como você pode implementá-los em sua própria blockchain.

Mão escrevendo 'Ethereum" em um quadro 'white board'.
Imagem: pexels.com

Se no primeiro volume vimos a estrutura básica do bloco e da blockchain, aqui começamos a plantar os mecanismos que darão vida às aplicações descentralizadas (dApps). Seja para transferências automatizadas, registros imutáveis ou lógica condicional entre partes, os contratos inteligentes são a chave para desbloquear o verdadeiro potencial da Web3.


🚀 Integrando Contratos Inteligentes à Sua Blockchain

Contratos inteligentes permitem acordos automatizados e autoexecutáveis sem a necessidade de uma autoridade central. Você pode implementá-los diretamente na sua blockchain para viabilizar funcionalidades como transferência de ativos, validação de transações ou execução de aplicativos descentralizados (dApps).

🌐 Visão Geral dos Contratos Inteligentes

Contratos inteligentes são programas que rodam na blockchain. Eles podem ser escritos em linguagens como Solidity (comumente usada no Ethereum) ou Vyper, e têm como objetivo automatizar acordos ou transações entre partes.

Em sua blockchain baseada em Go, você essencialmente precisará de:

  • Uma forma de armazenar contratos inteligentes na blockchain.
  • Um mecanismo para executar o código do contrato inteligente quando certas condições forem atendidas.

Vamos simular isso de forma simples para começar, utilizando as capacidades nativas do Go. Isso não será tão complexo quanto o Ethereum, mas ilustrará os conceitos. Se você quiser avançar para contratos inteligentes compatíveis com o Ethereum, precisará de Solidity e de um cliente Ethereum como Geth ou Parity.

Abordagem Básica para Integrar Contratos Inteligentes

1️⃣ Representar Contratos Inteligentes

Em Go, você pode representar um contrato inteligente criando uma estrutura (struct) para o código do contrato e seu estado. Vamos começar definindo um contrato inteligente simples que pode atualizar seu estado quando chamado.

type SmartContract struct {
	ID    int
	Code  string  // Este pode ser o código do contrato (por exemplo, código Solidity ou pseudo-código)
	State string  // Armazena o estado do contrato (por exemplo, "ativo", "concluído", etc.)
}

2️⃣ Adicionar Contratos Inteligentes aos Blocos

Você pode modificar a estrutura do bloco para incluir um contrato inteligente em cada bloco.

type Block struct {
	Index         int
	Timestamp     string
	Data          string // Dados da transação ou do contrato inteligente
	PrevHash      string
	Hash          string
	SmartContract *SmartContract // Adiciona um ponteiro para o contrato inteligente (se houver)
}

Ao adicionar um novo bloco, você pode verificar se o bloco deve conter um contrato inteligente e configurá-lo.

func (bc *Blockchain) addBlockWithContract(data string, contract *SmartContract) {
	prevBlock := bc.Chain[len(bc.Chain)-1]
	newBlock := Block{
		Index:         prevBlock.Index + 1,
		Timestamp:     time.Now().String(),
		Data:          data,
		PrevHash:      prevBlock.Hash,
		Hash:          calculateHash(prevBlock.Index+1, prevBlock.Hash, data),
		SmartContract: contract,
	}
	bc.Chain = append(bc.Chain, newBlock)
}

3️⃣ Simular a Execução do Contrato

Uma maneira básica de simular a execução de um contrato é chamando uma função no SmartContract quando certas condições forem atendidas.

Vamos supor que você tenha um contrato que permite alguém “ativá-lo” e definir seu estado como “concluído”:

func (sc *SmartContract) execute() {
	// Para este exemplo simples, vamos dizer que executar significa mudar o estado
	if sc.State == "ativo" {
		sc.State = "concluído"
		fmt.Println("Contrato executado com sucesso!")
	} else {
		fmt.Println("Contrato já está concluído!")
	}
}

Então, na sua blockchain, você poderia ter uma função que verifica se há contratos que precisam ser executados quando um novo bloco é adicionado:

func (bc *Blockchain) executeContracts() {
	for _, block := range bc.Chain {
		if block.SmartContract != nil && block.SmartContract.State == "ativo" {
			block.SmartContract.execute()
		}
	}
}

4️⃣ Acionar Contratos Inteligentes

Agora você pode executar a lógica do contrato inteligente ao adicionar blocos à sua blockchain:

func main() {
	blockchain := Blockchain{}
	blockchain.Chain = append(blockchain.Chain, createGenesisBlock())

	// Cria um novo contrato inteligente
	contract := &SmartContract{
		ID:    1,
		Code:  "transferir(100 tokens)",
		State: "ativo", // Inicialmente ativo, pode ser executado
	}

	// Adiciona o contrato a um novo bloco
	blockchain.addBlockWithContract("Dados da Transação", contract)

	// Executa quaisquer contratos ativos
	blockchain.executeContracts()

	// Imprime a blockchain para verificar o estado do contrato
	for _, block := range blockchain.Chain {
		fmt.Printf("Bloco %d: %s - Estado do Contrato: %s\n", block.Index, block.Timestamp, block.SmartContract.State)
	}
}

5️⃣ Expandir os Contratos Inteligentes

Para tornar este sistema mais semelhante ao que você veria com contratos inteligentes baseados no Ethereum, você poderia:

  • Adicionar uma linguagem (como Solidity) para escrever contratos mais complexos.
  • Usar uma máquina virtual para executar a lógica do contrato (semelhante à EVM do Ethereum).
  • Adicionar mecanismos de gás para limitar quanto de recursos cada execução de contrato consome.
  • Implementar um algoritmo de consenso para execução descentralizada (Proof of Work, Proof of Stake, etc.).

Considerações do Mundo Real

Para integrar completamente contratos inteligentes em uma blockchain:

  • Armazenamento de dados: Armazene o código e os estados do contrato de forma descentralizada (por exemplo, IPFS ou em seus blocos).
  • Ambiente de execução: Você precisará implementar um sistema para interpretar e executar o código do contrato de forma segura. Isso poderia ser semelhante à Máquina Virtual Ethereum (EVM), mas poderia ser muito mais simples na sua blockchain baseada em Go.
  • Segurança: Contratos inteligentes podem ser vulneráveis a ataques como reentrância ou bugs de estouro. Lidar com isso de forma segura é crucial (por exemplo, testando contratos minuciosamente).

Conectar a um Contrato Inteligente baseado em Ethereum (Avançado)

Se você está procurando conectar sua blockchain Go ao Ethereum ou a uma blockchain semelhante ao Ethereum para executar contratos inteligentes Solidity, aqui está a abordagem geral:

  1. Instalar o Web3 para Go: Esta é uma biblioteca Go que permite interagir com contratos inteligentes do Ethereum. go get github.com/ethereum/go-ethereum
  2. Conectar-se ao Ethereum: Você precisará configurar um nó Ethereum (por exemplo, usando Infura ou executando seu próprio nó) e usar o Web3 em Go para implantar e interagir com contratos inteligentes.

Aqui está um exemplo:

package main

import (
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/accounts/abi"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    client, err := ethclient.Dial("https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID")
    if err != nil {
        log.Fatalf("Falha ao conectar ao cliente Ethereum: %v", err)
    }

    address := common.HexToAddress("0xYourContractAddress")

    fmt.Println("Conectado ao Ethereum!")
    fmt.Println("Endereço do Contrato:", address.Hex())
}

Nesta segunda parte, exploramos na prática como os contratos inteligentes funcionam dentro de uma blockchain. Em breve vamos aprofundar ainda mais: analisando padrões de contratos inteligentes, interações entre múltiplos contratos e desafios reais como segurança, escalabilidade e integração com redes como Ethereum.

O futuro é descentralizado — e ele começa com nossas linhas de código.

Guia Prático: Blockchain e Contratos Inteligentes I

Há muito tempo tenho vontade de criar um tutorial. No entanto, sempre tive um certo pudor, além do receio de ser (percebido como) apenas mais um.

Imagem decorativa do texto, mostrando objetos de escritório em torno da palavra 'blockchain'
Imagem: pexels.com

Sempre estabeleci como condição para um tutorial que o assunto tratado fosse realmente relevante e original. Agora, finalmente, surge a oportunidade de desenvolver um tutorial original sobre esse sistema importante, ainda pouco compreendido, mas cada vez mais presente na realidade do mundo moderno.

A mídia fala constantemente sobre blockchain e seus derivados — como as criptomoedas e os contratos inteligentes mas, para muitos, incluindo colegas de profissão, esses conceitos ainda são envoltos em uma névoa de imprecisão, quando não de total confusão. Este guia tem como objetivo destacar o aspecto concreto dessas tecnologias, trazendo à tona sua implementação real por meio de código, e mostrando, na prática, como interagir com elas dentro do ambiente computacional.

Neste tutorial uso a linguagem Go, tanto pela simplicidade como por seu uso crescente nos projetos voltados à Blockchain. Qualquer LLM poderá refatorar o código facilmente para qualquer outra linguagem, como Python.


O que é uma Blockchain?

O termo “blockchain” vem da junção das palavras em inglês block (bloco) e chain (cadeia), e descreve exatamente o que ela é: uma cadeia de blocos ligados entre si, onde cada bloco contém um conjunto de dados, um carimbo de data/hora (timestamp), e um hash que o conecta ao bloco anterior. Essa estrutura torna os dados praticamente imutáveis, sendo largamente usada para garantir transparência e segurança em ambientes descentralizados.

Um Pouco de História

A ideia de encadear blocos usando hashes não surgiu com o Bitcoin. Já em 1991, Stuart Haber e W. Scott Stornetta propuseram um sistema computacional para armazenar documentos com carimbos de tempo de forma segura — sem possibilidade de adulteração. Esse trabalho é considerado uma das raízes da blockchain moderna. Foi somente em 2008 que Satoshi Nakamoto uniu essa ideia com o conceito de dinheiro digital, criando o Bitcoin e, com ele, a blockchain como a conhecemos hoje.


Conceitos-chave para Entender

🧩 Bloco

Cada bloco é como uma página em um livro-razão digital. Ele possui:

  • Carimbo de data/hora (T1, T2, T3…): Indica quando o bloco foi criado.
  • Hash do bloco anterior (PreHash): Uma “impressão digital” do bloco anterior, que o conecta à cadeia.
  • Hash atual (Root Hash): Calculado com base no conteúdo do bloco e serve para garantir sua integridade.
  • Dados: Pode conter qualquer informação — transações financeiras, contratos, documentos, etc.
Figura 1 - Diagrama ilustrativo da blockchain.
Fig 1 – Ilustração da estrutura de um bloco.

Como se vê, o hash do bloco anterior se liga ao hash atual, conectando a cadeia. Se qualquer informação em um bloco for alterada, seu hash muda. Isso quebra a cadeia, tornando evidente que houve uma tentativa de adulteração.

🔐 Hashing

Hashing é o processo de aplicar uma função criptográfica sobre um dado para obter uma sequência de caracteres (o hash). Um dos algoritmos mais usados é o SHA-256, criado pela NSA e adotado amplamente desde os anos 2000. Ele transforma qualquer entrada (como um texto ou número) em uma sequência hexadecimal de 64 caracteres. Pequenas mudanças no dado original geram hashes completamente diferentes — um princípio chamado efeito avalanche.

⛏️ Prova de Trabalho (Proof of Work)

A Prova de Trabalho surgiu para resolver o problema da confiança em redes descentralizadas, como no Bitcoin. Ela exige que os participantes gastem poder computacional para adicionar novos blocos, tornando ataques muito caros e, portanto, inviáveis. A ideia foi inspirada em sistemas anti-spam dos anos 90 (como o Hashcash de Adam Back), onde uma tarefa computacional dificultava o envio de emails em massa.


🛠️ Construindo uma Blockchain Simples em Go

Agora que (provavelmente) entendemos os conceitos, vamos ver como isso se traduz em código.


Etapa 1: Definir a Estrutura do Bloco

package main

import (
    "crypto/sha256"
    "fmt"
    "time"
)

type Block struct {
    Index     int
    Timestamp string
    Data      string
    PrevHash  string
    Hash      string
}

🧱 Aqui definimos os principais componentes do bloco. Veja que a estrutura lógica do bloco define todos os ítens (atributos) do bloco, como ilustrado na Fig 1. Ele é uma estrutura básica, mas com tudo o que precisamos para construir a cadeia.


Etapa 2: Criar o Bloco Gênesis

func createGenesisBlock() Block {
    return Block{
        Index:     0,
        Timestamp: time.Now().String(),
        Data:      "Genesis Block",
        PrevHash:  "",
        Hash:      calculateHash(0, "", "Genesis Block"),
    }
}

📜 O bloco gênesis é o primeiro bloco da blockchain. Ele é especial porque não possui um antecessor. No Bitcoin, ele foi minerado por Satoshi Nakamoto em 3 de janeiro de 2009. Uma curiosidade: sua mensagem de dados incluía o título de uma manchete de jornal daquele dia, uma crítica à crise bancária da época.


Etapa 3: Função de Hash

func calculateHash(index int, prevHash, data string) string {
    record := fmt.Sprintf("%d%s%s", index, prevHash, data)
    hash := sha256.New()
    hash.Write([]byte(record))
    return fmt.Sprintf("%x", hash.Sum(nil))
}

🔍 Essa função garante a integridade do bloco, produzindo um hash único com base nas suas informações. Isso é o que torna a blockchain resistente a modificações: se qualquer dado mudar, o hash será diferente.


Etapa 4: Criar a Blockchain

type Blockchain struct {
    Chain []Block
}

func (bc *Blockchain) addBlock(data string) {
    prevBlock := bc.Chain[len(bc.Chain)-1]
    newBlock := Block{
        Index:     prevBlock.Index + 1,
        Timestamp: time.Now().String(),
        Data:      data,
        PrevHash:  prevBlock.Hash,
        Hash:      calculateHash(prevBlock.Index+1, prevBlock.Hash, data),
    }
    bc.Chain = append(bc.Chain, newBlock)
}

🔗 Aqui a cadeia começa a tomar forma. Cada novo bloco contém o hash do anterior, criando a estrutura de “cadeia”.


Etapa 5: Iniciar e Usar a Blockchain

func main() {
    blockchain := Blockchain{}
    blockchain.Chain = append(blockchain.Chain, createGenesisBlock())

    blockchain.addBlock("Primeiro bloco depois do genesis")
    blockchain.addBlock("Segundo bloco depois do genesis")

    for _, block := range blockchain.Chain {
        fmt.Printf("Index: %d, Timestamp: %s, Data: %s, PrevHash: %s, Hash: %s\n",
            block.Index, block.Timestamp, block.Data, block.PrevHash, block.Hash)
    }
}

📤 A execução do código imprime cada bloco da cadeia, demonstrando como a estrutura vai se formando e se conectando.


Etapa 6: Saída Esperada

Index: 0, Timestamp: ..., Data: Genesis Block, PrevHash: , Hash: 6b3d...
Index: 1, Timestamp: ..., Data: Primeiro bloco depois do genesis, PrevHash: 6b3d..., Hash: 2c6e...
Index: 2, Timestamp: ..., Data: Segundo bloco depois do genesis, PrevHash: 2c6e..., Hash: 9c4a...

📊 Você verá blocos encadeados, com cada PrevHash correspondendo ao Hash do bloco anterior.


🧠 O que mais?

A blockchain construída acima é funcional, mas ainda simples. Você pode expandir com:


Validação da Blockchain

func (bc *Blockchain) isValid() bool {
    for i := 1; i < len(bc.Chain); i++ {
        prevBlock := bc.Chain[i-1]
        block := bc.Chain[i]
        if block.PrevHash != prevBlock.Hash || block.Hash != calculateHash(block.Index, block.PrevHash, block.Data) {
            return false
        }
    }
    return true
}

🔎 Esta função verifica se a cadeia é válida. É um conceito essencial para detectar fraudes ou inconsistências em sistemas descentralizados.


🔨 Prova de Trabalho (Opcional)

Você pode implementar um campo nonce no bloco e ajustar o algoritmo de hash para que o resultado comece com, por exemplo, “0000”. Isso simula a mineração usada no Bitcoin, onde é preciso tentar milhões de combinações até encontrar um hash com a “dificuldade” exigida.


🌐 Descentralização

Até agora, nossa blockchain é local e centralizada. Em um projeto mais complexo, você pode usar:

  • Go-Ethereum: Implementação oficial do Ethereum em Go.
  • Gorilla Websocket: Para comunicação P2P entre nós (nodes).
  • Go-Swagger: Para criar APIs REST que expõem a blockchain.

🎓 Conclusão da primeira parte

Construir uma blockchain do zero é uma excelente forma de aprender estruturas de dados, criptografia, segurança da informação e sistemas distribuídos. Começando com algo simples, você pode continuar a adicionar camadas de complexidade: provas de consenso, contratos inteligentes, persistência em disco, interfaces gráficas e muito mais.

Se você chegou até aqui você está mais perto de entender não só como a blockchain funciona, mas por que ela é revolucionária. Na segunda parte deste pequeno guia, vou mostrar a lógica estrutural de um contrato inteligente e como adicioná-lo à Blockchain.

Estou desenvolvendo um tutorial completo (e executável!) sobre o tema, que abrigarei em meu Github. Você pode acompanhar — e contribuir.

Esse Estranho Capitalismo Virtual

A indústria de Tecnologia, Informação e Comunicação (TIC) tem uma questão interessante, e os economistas profissionais aparentemente não gostam de falar sobre ela.

Imagem: Pexels

Em praticamente todos os setores da economia o preço de um bem sobe mais rápido do que sua utilidade, um fenômeno intrinsecamente “inflacionário”. Portanto, há pouco sentido em adiar uma compra – logo, compre um apartamento ou casa o mais cedo possível.

Agora considere os computadores, um item cujo desempenho (utilidade) historicamente dobrou a cada 18 meses, segundo a progressão conhecida como Lei de Moore. No entanto, o preço deles em moeda fiduciária permaneceu relativamente estável. Ou seja, R$ 1.500 sempre deram acesso a um moderno laptop para consumo ou negócios, ano após ano.

Enquanto isso, a maioria das outras coisas sofria com uma inflação da moeda fiduciária de cerca de 3% ao ano. Portanto, depois de uma década, o que custava $100 agora fora reajustado para ~ $134. Note que com a economia pagando, na melhor das hipóteses, cerca de 2% de rendimento, você só teria ~ $125 guardados na poupança nesse mesmo período.

Assim, quando você quisesse comprar um laptop de ponta, seus $ 1.500 no banco, depois de uma década, teriam chegado a $1.875 ($375 a mais). Contudo, o computador seria 100 vezes mais poderoso. Do ponto de vista econômico, isso representa uma deflação muito séria e muito prejudicial. Portanto, pelas normas da economia clássica, a industria de TIC não deveria existir – nem qualquer outra indústria de eletrônicos de consumo.

O capitalismo virtual

Esse problema estava se espalhando para o mercado automotivo, devido à eletrônica embarcada, o que estava se mostrando prejudicial de várias maneiras.

No entanto, e esse é o novo fenômeno, alguns fabricantes automotivos agora não mais “vendem” carros aos consumidores. Em em vez disso eles agora usam expressões como “buy back” ou “trade up“- uma espécie de leasing rebatizado. Em essência, fazem você pagar uma taxa de uso mensal indefinidamente. Eles apenas te dão outro carro, com cada vez mais componentes eletrônicos, a cada três anos – o que ainda é efetivamente deflacionário pelas regras dos economistas clássicos.

Alguns fabricantes de carros de ponta nem tentam esconder o fato de que os seus produtos vêm com todos os recursos possíveis já embutidos – só que desativados. Se você pagar um pouco a mais a cada mês, eles vão permitir que você os use, bastando apenas uma atualização remota do cṍdigo.

Você não é proprietário legítimo do carro [arrisco dizer que, nessas condições, dar certos comandos de voz em tons mais ríspidos poderia trazer apuros jurídicos].

Além disso, como reza o contrato [que você talvez não tenha lido], você precisa também dar a eles a sua alma, em forma de um dilúvio de informações pessoais.

Um sabor de mercantilismo

As velhas regras da economia estão se tornando menos relevantes à medida que somos forçados a uma economia rentista da qual não se pode escapar. Veja assim o futuro próximo: perca sua renda por algum motivo e eles, remotamente, desligam tudo o que você achava que possuía. Mesmo assim todas as coisas ao seu redor ainda vão continuar a espionar você minuto a minuto, dia a dia – porque para se desconectar é preciso usar uma das funcionalidades que eles desativaram remotamente. Nada como a proverbial “liberdade capitalista”.

De qualquer forma, em um futuro próximo certamente haverá alguma cláusula legal para fazer você pagar um montante adicional para ser excluído da vigilância.

Pelo que me disseram, as telecoms americanas chegaram muito perto desse modelo, ou de algo que serviria de trampolim para ele. O usuário pagaria pelo plano de conectividade – em oposição a um modelo grátis baseado em anúncios – mas mesmo assim as empresas o espionariam e venderiam os dados coletados.

Se você quisesse o plano “sem vigilância”, a ideia era que você teria que pagar mais, com todos os tipos de outros penduricalhos, etc., totalizando algo como $30/mês a mais – eles ainda iriam espionar e coletar dados, mas não “vendê-los” enquanto você continuasse a pagar o “resgate” [como em um sequestro].

Não ficou claro o que eles queriam dizer com “não vender” e não havia garantia de que eles não venderiam todos os seus dados privados em uma data posterior – aparentemente alguém decidiu que o mercado ainda não estava pronto para essa opção, “ainda”.

Post scriptum

O capitalismo tem perdido também outras dimensões. Acabamos de ver aqui como o capitalismo está rapidamente se dissociando da ideia de “propriedade”.

Mas nem é preciso uma análise atenta para ver que o conceito de concorrência está sendo pulverizado por monopólios cada vez mais poderosos. Noções mais abstratas e difusas, como virtude, pudor, modéstia e mérito, tão sagradas à clássica moral capitalista protestante, já foram extintas pela brutal economia da atenção e pelo imediatismo narcisista das redes sociais, em que é possível encontrar completos imbecis a fazer fortunas da noite para o dia, e a ditar o ethos da época [o que alguns chamam de zeitgeist].

Eticamente, o capitalismo está em frangalhos, desta vez muito mais do que esteve em qualquer período da história, e a marcha de sua insensatez parece apenas se acelerar. O capitalismo se parece cada vez mais com o seus antecessores primitivos, o feudalismo e o mercantilismo. A social-democracia de tempos atrás, praticamente extinta, me parece agora um regime muito mais sofisticado e justo – e em 1989 parecia, de fato, ter vencido a História.

Realmente, só se dá valor ao que se perde.

A Visão do Computador, Nós e os Presidenciáveis

Neste post vou abordar um assunto com o qual os leitores podem facilmente se identificar, pois o que vamos discutir está firmemente arraigado em nossa vida diária. Faça um esforço para ler até o fim. Você pode se surpreender e até gostar.

Arte: Vox Leone

Como já informei, aqui em nosso lab temos usado o incrível Jupyter Notebook, nas tarefas rotineiras de análise de dados, e também em pesquisas relacionadas à visão de computador e processamento de linguagem natural. Isso nos permite colaborar (trabalhar em rede), consolidar dados que serão usados em outras fases do trabalho e gerar as mais diversas visualizações, que são necessárias nas relações com clientes e o público geral.

Nas últimas semanas estive absorvido na tarefa de desenvolver nossa própria aplicação de reconhecimento facial, usando tecnologias populares na área, como Tensorflow, Computer Vision 2, Matplotlib e Pandas. Tudo orquestrado pela excelente biblioteca DeepFace, que disponibiliza oito modelos pré-treinados.

Os resultados que tivemos foram impressionantes. Animado com os experimentos, preparei este Notebook para demonstrar aos leitores como somos vistos pelos olhos digitais que pululam ao nosso redor (sempre em detrimento de nossa privacidade) e quais as tecnologias empregadas.

Os aeroportos resumem a experiência. Todos sabem que ao entrar nesse tipo de ambiente nós somos enquadrados de todos os ângulos imagináveis, por sensores cada vez mais sofisticados, entre os quais se destacam os onipresentes sensores óticos. Já discutimos neste blog – e vamos continuar – algumas questões éticas e legais a respeito do assunto, mas hoje quero demonstrar sucintamente como a análise facial é feita materialmente e quais as informações que os sistemas de vigilância podem obter bastando apenas voltar seu olhar em nossa direção.

A Tecnologia

Vou ter que usar um pouco de código, e algum jargão, mas você pode pular até o resultado da análise da imagem e discussão, mais abaixo.

Seguindo a tendência de grande parte da indústria, nossa aplicação – escrita em Python – é desenvolvida e executada dentro de um ambiente virtual Conda. O núcleo do ambiente é a versátil biblioteca DeepFace, desenvolvida pela Alphabet (Google), aqui instalada através do repositório pip. (*)ressalto que não é recomendado misturar os canais dos repositórios Conda e pip em um mesmo ambiente, mas neste experimento se torna necessário usar pip pelo fato de DeepFace ainda não estar disponível no repositório Conda.

Depois de ter instalado a DeepFace e suas dependências no ambiente virtual, iniciamos o script importando a DeepFace e outras bibliotecas das quais ela depende, como TensorFlow, CV2 e Matplotilb. TensorFlow é o motor da aplicação. CV2 é responsável pela visão de computador, neste caso digitalizando apropriadamente as imagens. Matplotlib é a responsável pela renderização das imagens (plotagem). Vou comentar o código com as explicações.

Análise dos resultados

Et voilà! Depois de alguns segundos temos o resultado da análise. O algoritmo, mesmo nesta configuração básica, é sensível o bastante para detectar sete variações emocionais, além da idade aparente e do gênero. Ele também é capaz de diferenciar seis etnicidades, um tanto arbitrárias, devo dizer, espelhando a classificação dos países anglo-saxões.

Eu anoto neste ponto que usamos a biblioteca DeepFace em sua configuração original, assim como o modelo de aprendizado de máquina pré-treinado em bancos de imagens com milhões de amostras. Não tivemos ainda tempo hábil para introduzir grandes modificações no código e treinar nossos próprios modelos, o que já está sendo feito – e será mostrado oportunamente.

Esta é a análise que os sistemas fazem sobre mim [sobre nós] no momento em que saio do táxi na porta do aeroporto.

É uma análise aparentemente trivial de uma imagem trivial. Contexto real da foto: acabei de chegar a uma chácara para uma festa de aniversário – alguns anos atrás.

A Análise

O algoritmo me interpreta como um homem branco de aparentes 37 anos – sendo agradavelmente generoso na avaliação etária. É interessante que ele me atribui uma certa negritude, como alternativa, muito mais do que seria esperado de minha ascendência mediterrânea, que fica relegada a um baixíssimo patamar de probabilidade. Minha expressão é calma, que o algoritmo traduz como neutra. Como indicam os números na tabela em inglês, posso estar também um pouco triste, e com um certo nojinho.

Contudo, o resultado me atribui uma significativa aparência de medo, como o segundo resultado mais provável. Por que eu estaria com medo nesta foto? Acabei de chegar a uma festa e a tarde de sábado parece promissora – no aeroporto isso acenderia uma luz amarela no centro de comando da segurança. Interrompo o teste e começo a tentar entender esse resultado aparentemente divergente.

Depois de algumas horas eu tive um insight que realmente me encantou. Eu entendi que, de fato, o algoritmo havia conseguido ver através da minha máscara social. Ele captou uma verdade íntima e bastante sutil: eu realmente sou ansioso em situações sociais, e sempre demoro um pouco a me adaptar aos ambientes – valentemente, com um sorriso no rosto. Mas a ansiedade – uma forma de medo – deve sulcar nossa face de uma maneira óbvia a sistemas de precisão, que conhecem dezenas de milhões de rostos que respondem sempre da mesma maneira; da mesma maneira humana demais. Minúsculos espasmos musculares, resultantes de nossas emoções, não importa quão sutis, deixam sua marca em nossa face, e em imagens de alta resolução nos desnudam de qualquer abrigo.

Ver o sistema em ação elevou em vários graus minha confiança na tecnologia [além de uma óbiva inquietação]. Depois de muitas rodadas do sistema, com imagens diferentes, eu tenho razões para crer que esse tipo de algoritmo é consistente na detecção de sinais e marcadores de emoções bastante sutis.

Revelando emoções ocultas

Existe uma atividade humana em que ser capaz de detectar as emoções alheias seria de muita utilidade: a política, por exemplo. Seria do maior interesse público tentar sondar os reais sentimentos daqueles que se apresentam para gerir a coisa pública. Nessa atividade em que a manipulação das emoções é tão corriqueira, seria interessante tentar ver através das máscaras.

Acontece que em abril de 2022 nós temos essas fantásticas ferramentas e estamos aprendendo a dominá-las. Vamos tentar, então, fazer a mesma análise que fiz acima, de mim mesmo, em imagens casuais dos principais políticos que se apresentam para a disputa presidencial deste ano. Vamos usar fotos tiradas da internet e submetê-las ao mesmo algoritmo.

Com certeza os candidatos não vão se importar, pois todos eles, com palavras ou atos, já se manifestaram apoiadores da vigilância eletrônica na vida do cidadão. É uma ironia deliciosa poder usar contra os representantes do sistema a mesma tecnologia que o sistema usa para nos oprimir delicadamente. Vai ser, no mínimo, divertido.

Nota: as imagens abaixo foram buscadas no site da Wikimedia Commons. Foram escolhidas por serem adequadas a este projeto. São apresentadas na ordem alfabética dos sobrenomes dos retratados.

Este Notebook é melhor visualizado em um desktop.

Bolsonaro, Jair

O perfil de Bolsonaro revela uma grande carga de emotividade. Uma mistura de raiva, medo e tristeza, indicando um rosto que quer esconder o que sente. O modelo também é generoso na atribuição da idade, desvio que foi notado em todas as imagens analisadas [creio que sei a razão para isso, que comento na conclusão do artigo].

Dória, João

Vamos concordar que a imagem não precisa de análise por AI. Embora o modelo opte pela etnicidade Latina, na verdade ele se mostra indeciso. Isso implica em um certo viés colorista. Comento na conclusão.

Gomes, Ciro

Uma expressão neutra com um forte sinal – isolado – de tristeza. Minha avaliação humana concorda.

Lula da Silva, Luiz Inácio

Tristeza generalizada, com um sinal de nojo/desconforto [talvez pela situação]. A idade também é grandemente descontada.

Moro, Sérgio

A raiva e a tristeza predominam. O desvio etário se mostra menor. Um autêntico Latino Hispânico.

Tebet, Simone

Embora não esteja exibindo um sorriso exuberante [como Dória], o modelo atribuiu à imagem um sinal de alegria muito sólido. Não há emoções conflitantes, indicando sinceridade e abertura. A discrepância etária também é menor aqui. Surpreendentemente o modelo não atribui um peso muito forte à herança árabe da senadora.

Conclusão e notas

Como eu disse anteriormente, o modelo Facenet, um dos oito implementados na biblioteca DeepFace, se comporta de forma muito satisfatória. É preciso lembrar que o modelo reflete a amostra com a qual foi treinado. A medida que mais iterações do processo de treinamento venham a incorporar mais e mais segmentos populacionais, a precisão deverá aumentar.

Deixo uma crítica à classificação étnica empregada pelo modelo. Ela reflete a abordagem do censo americano, mas claramente não é mais adequada. Uma revisão se impõe. Os desvios notados com relação à idade das pessoas analisadas, se devem, provavelmente, à baixa resolução das imagens, que nivela os valores dos pixels dando margem a um enganoso efeito de filtro. A discrepância parece ser diretamente proporcional à idade do analisado [quanto mais idoso, maior a discrepância]. Esse desvio é responsável também pelo ‘colorismo’ do software, que dá grande peso à palidez aparente da imagem na classificação étnica.

Vamos continuar experimentando e trabalhando para tornar o modelo mais fiel às nossas características.

Referências

Jupyter Notebook – https://jupyter.org/

Anaconda – https://anaconda.org/

DeepFace – https://github.com/serengil/deepface

TensorFlow – https://www.tensorflow.org/

Jupyter Notebook: você um dia vai usar

JJupyter Notebooks