Introdução
Rust se tornou a linguagem dominante no ecossistema blockchain e Web3. Diferente de outras áreas da tecnologia onde Rust compete com várias linguagens, no mundo cripto Rust é a escolha praticamente unânime para as plataformas de nova geração. Solana, Polkadot, Near Protocol, Aptos, Sui e dezenas de outras blockchains importantes foram construídas em Rust. O motivo é claro: blockchains exigem exatamente o que Rust oferece de melhor — performance previsível, segurança de memória (bugs de memória em smart contracts podem significar milhões perdidos), controle fino sobre recursos e binários determinísticos.
Se você é desenvolvedor Rust ou quer entrar no mercado Web3, este artigo vai guiá-lo pelas principais plataformas, mostrar como escrever smart contracts e apresentar as oportunidades profissionais nesse setor.
Por Que Rust Domina o Web3?
- Segurança crítica: Bugs em smart contracts podem custar milhões de dólares. O sistema de tipos de Rust e o borrow checker eliminam classes inteiras de vulnerabilidades antes do deploy
- Performance: Blockchains processam milhares de transações por segundo. A performance zero-overhead de Rust é essencial
- Determinismo: O comportamento previsível de Rust (sem GC, sem runtime) garante execução determinística, fundamental para consenso
- Ecossistema de crates: Criptografia (ring, ed25519), serialização (borsh, serde), networking (tokio, libp2p) — tudo disponível e auditado
- WebAssembly: Muitas blockchains usam Wasm como formato de smart contract, e Rust tem o melhor suporte para compilação Wasm
Solana com Anchor Framework
Solana é a blockchain de alta performance mais popular, processando mais de 4.000 transações por segundo. O Anchor é o framework padrão para desenvolvimento de programas (smart contracts) na Solana.
Configuração do Projeto
# Cargo.toml
[package]
name = "votacao"
version = "0.1.0"
edition = "2021"
[dependencies]
anchor-lang = "0.30"
[lib]
crate-type = ["cdylib", "lib"]
name = "votacao"
Exemplo: Sistema de Votação On-Chain
use anchor_lang::prelude::*;
declare_id!("Vote111111111111111111111111111111111111111");
#[program]
pub mod votacao {
use super::*;
/// Cria uma nova enquete com as opções fornecidas.
pub fn criar_enquete(
ctx: Context<CriarEnquete>,
titulo: String,
opcoes: Vec<String>,
) -> Result<()> {
require!(opcoes.len() >= 2, ErroVotacao::MinimoOpcoes);
require!(opcoes.len() <= 10, ErroVotacao::MaximoOpcoes);
require!(titulo.len() <= 100, ErroVotacao::TituloLongo);
let enquete = &mut ctx.accounts.enquete;
enquete.autoridade = ctx.accounts.autoridade.key();
enquete.titulo = titulo;
enquete.opcoes = opcoes;
enquete.votos = vec![0u64; enquete.opcoes.len()];
enquete.total_votos = 0;
enquete.ativa = true;
msg!("Enquete criada: {}", enquete.titulo);
Ok(())
}
/// Registra um voto para a opção especificada.
pub fn votar(
ctx: Context<Votar>,
opcao: u8,
) -> Result<()> {
let enquete = &mut ctx.accounts.enquete;
let registro = &mut ctx.accounts.registro_voto;
require!(enquete.ativa, ErroVotacao::EnqueteInativa);
require!(
(opcao as usize) < enquete.opcoes.len(),
ErroVotacao::OpcaoInvalida
);
// Registrar que este eleitor já votou
registro.eleitor = ctx.accounts.eleitor.key();
registro.enquete = enquete.key();
registro.opcao = opcao;
// Contabilizar voto
enquete.votos[opcao as usize] += 1;
enquete.total_votos += 1;
msg!(
"Voto registrado: {} votou na opção '{}'",
ctx.accounts.eleitor.key(),
enquete.opcoes[opcao as usize]
);
Ok(())
}
/// Encerra a enquete (somente autoridade).
pub fn encerrar_enquete(ctx: Context<EncerrarEnquete>) -> Result<()> {
let enquete = &mut ctx.accounts.enquete;
require!(enquete.ativa, ErroVotacao::EnqueteInativa);
enquete.ativa = false;
msg!("Enquete '{}' encerrada", enquete.titulo);
Ok(())
}
}
// === Contas (Accounts) ===
#[account]
pub struct Enquete {
pub autoridade: Pubkey,
pub titulo: String,
pub opcoes: Vec<String>,
pub votos: Vec<u64>,
pub total_votos: u64,
pub ativa: bool,
}
#[account]
pub struct RegistroVoto {
pub eleitor: Pubkey,
pub enquete: Pubkey,
pub opcao: u8,
}
// === Contextos de Instrução ===
#[derive(Accounts)]
#[instruction(titulo: String, opcoes: Vec<String>)]
pub struct CriarEnquete<'info> {
#[account(
init,
payer = autoridade,
space = 8 + 32 + 4 + titulo.len() + 4 + opcoes.iter().map(|o| 4 + o.len()).sum::<usize>() + 4 + opcoes.len() * 8 + 8 + 1
)]
pub enquete: Account<'info, Enquete>,
#[account(mut)]
pub autoridade: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Votar<'info> {
#[account(mut)]
pub enquete: Account<'info, Enquete>,
#[account(
init,
payer = eleitor,
space = 8 + 32 + 32 + 1,
seeds = [b"voto", enquete.key().as_ref(), eleitor.key().as_ref()],
bump
)]
pub registro_voto: Account<'info, RegistroVoto>,
#[account(mut)]
pub eleitor: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct EncerrarEnquete<'info> {
#[account(
mut,
has_one = autoridade @ ErroVotacao::NaoAutorizado,
)]
pub enquete: Account<'info, Enquete>,
pub autoridade: Signer<'info>,
}
// === Erros Customizados ===
#[error_code]
pub enum ErroVotacao {
#[msg("A enquete precisa ter no mínimo 2 opções")]
MinimoOpcoes,
#[msg("A enquete pode ter no máximo 10 opções")]
MaximoOpcoes,
#[msg("O título não pode ter mais de 100 caracteres")]
TituloLongo,
#[msg("Esta enquete não está mais ativa")]
EnqueteInativa,
#[msg("Opção de voto inválida")]
OpcaoInvalida,
#[msg("Somente a autoridade pode executar esta ação")]
NaoAutorizado,
}
Polkadot com Substrate
Substrate é o framework para construir blockchains customizadas no ecossistema Polkadot. Ele permite criar parachains (blockchains paralelas) com lógica personalizada usando pallets:
[dependencies]
frame-support = { version = "36", default-features = false }
frame-system = { version = "36", default-features = false }
sp-runtime = { version = "39", default-features = false }
#[frame_support::pallet]
pub mod pallet_registro {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
#[pallet::constant]
type TamanhoMaximoNome: Get<u32>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
/// Armazenamento de registros on-chain.
#[pallet::storage]
#[pallet::getter(fn registros)]
pub type Registros<T: Config> = StorageMap<
_,
Blake2_128Concat,
T::AccountId,
BoundedVec<u8, T::TamanhoMaximoNome>,
OptionQuery,
>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Um novo registro foi criado.
RegistroCriado {
quem: T::AccountId,
nome: BoundedVec<u8, T::TamanhoMaximoNome>,
},
/// Um registro foi removido.
RegistroRemovido {
quem: T::AccountId,
},
}
#[pallet::error]
pub enum Error<T> {
NomeMuitoLongo,
RegistroJaExiste,
RegistroNaoEncontrado,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Cria um novo registro associado à conta do chamador.
#[pallet::call_index(0)]
#[pallet::weight(10_000)]
pub fn criar_registro(
origin: OriginFor<T>,
nome: BoundedVec<u8, T::TamanhoMaximoNome>,
) -> DispatchResult {
let quem = ensure_signed(origin)?;
ensure!(
!Registros::<T>::contains_key(&quem),
Error::<T>::RegistroJaExiste
);
Registros::<T>::insert(&quem, &nome);
Self::deposit_event(Event::RegistroCriado { quem, nome });
Ok(())
}
/// Remove o registro da conta do chamador.
#[pallet::call_index(1)]
#[pallet::weight(5_000)]
pub fn remover_registro(origin: OriginFor<T>) -> DispatchResult {
let quem = ensure_signed(origin)?;
ensure!(
Registros::<T>::contains_key(&quem),
Error::<T>::RegistroNaoEncontrado
);
Registros::<T>::remove(&quem);
Self::deposit_event(Event::RegistroRemovido { quem });
Ok(())
}
}
}
Near Protocol
Near Protocol usa Rust para smart contracts que compilam para WebAssembly:
[dependencies]
near-sdk = "5"
use near_sdk::borsh::{BorshDeserialize, BorshSerialize};
use near_sdk::{env, near_bindgen, AccountId, NearToken};
use near_sdk::collections::LookupMap;
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
#[borsh(crate = "near_sdk::borsh")]
pub struct Crowdfunding {
dono: AccountId,
meta: NearToken,
total_arrecadado: NearToken,
contribuicoes: LookupMap<AccountId, NearToken>,
encerrado: bool,
}
impl Default for Crowdfunding {
fn default() -> Self {
Self {
dono: env::predecessor_account_id(),
meta: NearToken::from_near(10),
total_arrecadado: NearToken::from_near(0),
contribuicoes: LookupMap::new(b"c"),
encerrado: false,
}
}
}
#[near_bindgen]
impl Crowdfunding {
#[init]
pub fn new(meta_near: u128) -> Self {
Self {
dono: env::predecessor_account_id(),
meta: NearToken::from_near(meta_near),
total_arrecadado: NearToken::from_near(0),
contribuicoes: LookupMap::new(b"c"),
encerrado: false,
}
}
#[payable]
pub fn contribuir(&mut self) {
assert!(!self.encerrado, "Campanha encerrada");
let contribuidor = env::predecessor_account_id();
let valor = env::attached_deposit();
let atual = self.contribuicoes
.get(&contribuidor)
.unwrap_or(NearToken::from_near(0));
self.contribuicoes.insert(
&contribuidor,
&atual.saturating_add(valor),
);
self.total_arrecadado = self.total_arrecadado.saturating_add(valor);
env::log_str(&format!(
"{} contribuiu com {} yoctoNEAR",
contribuidor,
valor
));
}
pub fn consultar_progresso(&self) -> String {
format!(
"Arrecadado: {} / Meta: {} | {:.1}%",
self.total_arrecadado,
self.meta,
(self.total_arrecadado.as_yoctonear() as f64
/ self.meta.as_yoctonear() as f64)
* 100.0
)
}
}
Blockchains Construídas com Rust
| Blockchain | Uso de Rust | TPS | Capitalização |
|---|---|---|---|
| Solana | Core + Smart contracts | ~4.000 | Top 5 |
| Polkadot | Core + Parachains (Substrate) | ~1.000 | Top 15 |
| Near Protocol | Core + Smart contracts | ~100.000 (sharded) | Top 30 |
| Aptos | Core (Move VM, runtime Rust) | ~160.000 | Top 30 |
| Sui | Core (Move VM, runtime Rust) | ~120.000 | Top 30 |
| Cosmos SDK | Partes do ecosistema | Variável | Top 20 |
| Zcash | Implementação zebra (Rust) | ~27 | Top 100 |
| Diem/Libra | Core (descontinuado, mas influente) | N/A | N/A |
Oportunidades Profissionais
O mercado Web3 para desenvolvedores Rust é extremamente aquecido:
- Salários: Desenvolvedores Rust/Solana nos EUA ganham entre $150k-$300k/ano; remoto do Brasil, entre $80k-$200k/ano
- Demanda: Há mais vagas do que desenvolvedores qualificados, criando um mercado favorável ao candidato
- Trabalho remoto: A maioria das empresas Web3 opera 100% remotamente
- Diversidade de projetos: DeFi, NFTs, DAOs, infraestrutura, bridges, oracles
Como Começar
- Domine Rust primeiro: O borrow checker e lifetimes são essenciais — primeiros passos
- Entenda traits e generics: Fundamento para Anchor e Substrate — tutorial de traits
- Escolha uma plataforma: Solana (mais vagas) ou Polkadot (mais complexo, projetos maiores)
- Para Solana: Instale Anchor CLI, estude o Anchor Book e comece com programas simples
- Para Polkadot: Clone o Substrate Node Template e estude os pallets existentes
- Veja vagas: Confira as oportunidades em Rust no Brasil e globalmente em cripto job boards
- Participe da comunidade: Superteam (Solana Brasil), Polkadot Brasil
Conclusão
Se você é desenvolvedor Rust e quer maximizar suas oportunidades profissionais, o ecossistema blockchain/Web3 oferece a melhor combinação de demanda alta, salários competitivos e trabalho remoto. Plataformas como Solana e Polkadot investem fortemente em tooling e documentação, tornando a entrada mais acessível do que nunca. O investimento em aprender Rust se paga multiplicado no mercado Web3.
Veja Também
- Vagas Rust no Brasil — Oportunidades de trabalho com Rust, incluindo Web3
- Empresas que Usam Rust — Conheça empresas do ecossistema
- Tutorial: Traits e Generics — Conceito fundamental para smart contracts
- Rust para WebAssembly — Muitas blockchains usam Wasm como formato de contrato
- Rust para Desenvolvimento Web — Construa frontends e APIs para dApps
- Rust para Microsserviços — Infraestrutura de backend para Web3