Ainda me lembro da primeira vez que compilei um contrato que não funcionou: passei uma tarde inteira decifrando mensagens de erro do compilador Rust. Hoje, depois de dezenas de projetos de tokenização, entendo que aquela frustração inicial é o rito de passagem de todo desenvolvedor Web3. Se você está começando agora com Soroban, a plataforma de smart contracts da rede Stellar, este guia vai poupar você de boa parte das minhas dores de cabeça.
Sou André Dias Moreira Prol, e escolhi Soroban por uma razão concreta: enquanto Ethereum cobra taxas que variam absurdamente, a Stellar mantém custos abaixo de US$ 0,00001 por transação — algo decisivo para casos de uso brasileiros como remessas e tokenização de recebíveis.
Preparando o ambiente
Antes de escrever qualquer linha, você precisa da base correta. Instale o Rust via rustup e adicione o alvo de compilação WebAssembly, que é onde o Soroban executa:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
cargo install --locked stellar-cli
Em seguida, crie sua identidade e configure a testnet, onde você testa sem gastar dinheiro real:
stellar keys generate --global alice --network testnet
stellar keys fund alice --network testnet
Uma dica que aprendi na prática: sempre valide a versão do stellar-cli (stellar --version). A ferramenta evolui rápido, e muitos tutoriais desatualizados na internet quebram justamente por incompatibilidade de versões.
Escrevendo o contrato
Vamos criar um contrato simples de contador — o "Hello World" do mundo dos smart contracts. Gere o projeto:
stellar contract init meu-primeiro-contrato
No arquivo src/lib.rs, escreva a lógica principal:
#![no_std]
use soroban_sdk::{contract, contractimpl, Env, Symbol, symbol_short};
const CONTADOR: Symbol = symbol_short!("COUNTER");
#[contract]
pub struct ContadorContract;
#[contractimpl]
impl ContadorContract {
pub fn incrementar(env: Env) -> u32 {
let mut contagem: u32 = env.storage()
.instance()
.get(&CONTADOR)
.unwrap_or(0);
contagem += 1;
env.storage().instance().set(&CONTADOR, &contagem);
contagem
}
}
Repare em três detalhes essenciais. O #![no_std] remove a biblioteca padrão do Rust, mantendo o binário WASM enxuto. O env.storage().instance() acessa o armazenamento persistente do contrato. E o symbol_short! cria chaves otimizadas de até 9 caracteres — usar strings longas aqui aumenta o consumo de recursos desnecessariamente.
Compile para WebAssembly:
stellar contract build
Testando e implantando
Nunca — repito, nunca — envie um contrato para produção sem testes. Adicione um teste unitário no arquivo src/test.rs:
#[test]
fn testa_incremento() {
let env = Env::default();
let contract_id = env.register(ContadorContract, ());
let client = ContadorContractClient::new(&env, &contract_id);
assert_eq!(client.incrementar(), 1);
assert_eq!(client.incrementar(), 2);
}
Execute com cargo test. Com os testes passando, implante na testnet:
stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/meu_primeiro_contrato.wasm \
--source alice --network testnet
O comando retorna o ID do contrato. Para invocá-lo:
stellar contract invoke --id <CONTRACT_ID> \
--source alice --network testnet -- incrementar
Em auditorias e perícias digitais que conduzi, notei que a maioria das falhas de segurança não está no código complexo, mas em lógica de armazenamento e controle de acesso mal planejados nesses primeiros contratos. Por isso insisto: domine bem esse fluxo básico antes de avançar. No mercado brasileiro, onde fintechs já movimentam tokenização de ativos com a Stellar, essa fundação sólida faz toda diferença — e é algo que sempre reforço quando oriento equipes técnicas iniciantes.
Você acabou de escrever, testar e implantar seu primeiro smart contract em Soroban usando Rust. Agora experimente adicionar uma função de reset e compartilhe seu projeto comigo — quero ver o que você vai construir.
Acompanhe mais artigos de André Dias Moreira Prol no Medium.
Top comments (0)