Rand é de código aberto. O full node, o explorador, a bridge, a pesquisa de provas e os clientes de carteira vivem, cada um, em seu próprio repositório no GitHub. Leia o código, execute os testes, envie patches. Esta página é o mapa: onde cada componente mora, com o que é construído, até onde o sistema de provas avançou e onde ele para hoje.
Repositórios
| repositório | o que contém | linguagem |
|---|---|---|
randprotocol/fullnode | Full node e carteira de referência: HotStuff BFT encadeado, rede libp2p, o pool blindado de notas RAND, o verificador de provas do zkVM, JSON-RPC, a CLI de carteira rand e o prover delegado rand-prover. | Rust |
randprotocol/randscan.org | Explorador de blocos por trás de randscan.org: um indexador axum com API REST e WebSocket sobre PostgreSQL, e um frontend em Next.js. | Rust · TypeScript |
randprotocol/bridge | Bridge de guardiões para USDT e USDC a partir de Ethereum, Binance Smart Chain, Tron e Solana: os contratos de custódia, o formato de atestação compartilhado e seus vetores de teste. | Solidity · Rust |
randprotocol/zkp-circuits | Passo a passo de sistemas de prova (Groth16 vs STARK, pool blindado, assinaturas em anel, mixer), research/, o zkVM de referência da Rand, recursion/, a VM de recursão, a toolchain de guests e os dois tradutores, e os kernels CUDA. O build do fullnode exige este repositório clonado ao lado dele como circuits/. | Rust |
randprotocol/clients | Os clientes de carteira: desktop, web, iOS e Android. | Rust · Swift · Java · JavaScript |
A pilha
Rust de ponta a ponta. A Rand é uma chain própria: um nó HotStuff BFT com uma camada de gossip libp2p, um pool de notas totalmente blindado como livro-razão, assinaturas e cifragem de notas pós-quânticas, e o zkVM da Rand para computação confidencial, tudo no repositório fullnode. O sistema de provas em si é a parte sob pesquisa ativa, abaixo.
| camada | o que roda |
|---|---|
| Consenso | HotStuff BFT encadeado, quóruns ponderados por stake, commit de três cadeias |
| Rede | libp2p: TCP, Noise, Yamux, gossipsub, Kademlia, mDNS em LANs |
| Livro-razão | Pool blindado de notas: árvore Poseidon2 de profundidade 32, conjunto de nullifiers, um bundle de ativos ocultos 4-in-4-out por transação (2-in-2-out até a chain 13); desde a chain 17, uma segunda prova de autorização de tier 10 ao lado da prova do bundle (autorização dividida); desde a chain 18, envelopes de nota de 1.860 bytes com um memo cifrado |
| Tokens | RPL: um token é uma entrada de registro do livro-razão com um id rpl1…, não um contrato; ele se move como notas no mesmo pool |
| Staking | Registro público de validadores: bond a partir de um bundle, desvinculação de duas épocas, épocas de 1.000 blocos; desde a chain 20, um novo validador é admitido por votação do conjunto |
| Computação confidencial | zkVM da Rand: RV32IM sob um STARK em lote Plonky3, FRI com ocultação ZK, conjunto de restrições 8; desde a chain 18, uma chamada declara um limite de gas que o circuito impõe e paga por gas e por KiB; desde a chain 20, um programa mantém estado em células e guarda valor em um cofre (RPL-2) |
| Criptografia | Dilithium2 · ML-KEM-768 · Poseidon2 · BLAKE3 · ChaCha20-Poly1305 |
| Armazenamento | Um RocksDB por nó, commits com fsync, verificação de integridade na inicialização; poda de histórico opcional (--prune-history 24h), com nós de arquivo mantendo tudo |
| Bridge | Locks atestados por guardiões em quatro chains, com um quórum de coassinaturas Dilithium2 em cada mint; um ativo bridged é uma nota no mesmo pool |
| Linguagem | Rust em todo o código; Solidity para a bridge, TypeScript para o explorador |
Uma relação para todos os programas
A relação universal de execução do whitepaper, R_exec, existe como código: rand_zkvm, uma máquina RV32IM provada sob um único STARK em lote sobre Plonky3, no corpo Goldilocks. Ela prova que algum traço executou o programa hc até estas saídas públicas, sobre entradas comprometidas por um H_IN com sal, e nada sobre o programa jamais é parâmetro do verificador. Publicar um programa confidencial significa registrar um hash, nunca gerar um circuito sob medida.
O sistema de provas é transparente, sem trusted setup e sem curva de emparelhamento, e sua hipótese é uma função de hash resistente a colisões. Espera-se que todo outro componente que toque provas convirja para este crate, em vez de criar o seu. O crate vive em zkp-circuits/research e é incorporado ao fullnode no conjunto de restrições 8 (circuits aeacf31, fullnode v0.6.7 e v0.6.8). As tabelas e medições abaixo descrevem o conjunto de restrições 5 (marco M4.2), a menos que uma linha cite um conjunto posterior; foram extraídas de docs/zkvm.md, docs/zkvm-milestones.md e docs/confidential.md do fullnode, em 2026-09-13, e as medições são citadas como medidas em um laptop Apple Silicon, não como metas.
Oito tabelas em barramentos nomeados, uma nona sob demanda
Um compromisso, uma abertura FRI. As tabelas nunca chamam umas às outras; elas trocam fatos por barramentos LogUp nomeados (PROGRAM, PROGRAM_WORD, MEMORY, ALU, POSEIDON2, INPUT_DIGEST, INPUT_READ, KECCAK e as consultas de intervalo e de nibble) e o verificador confere que todo barramento fecha globalmente. O grau máximo de restrição de cada tabela é fixado por um teste abaixo do limite de 8 que o blowup do FRI permite.
| tabela | tipo | função |
|---|---|---|
program | witness | Palavras de instrução brutas decodificadas no circuito desde M3.4, digeridas pela cpu em hc |
cpu | witness | Uma linha por ciclo, mais linhas de digest que absorvem o programa em hc e as entradas com sal em H_IN |
memory | witness | Registradores e RAM em uma só tabela, ordenados por (space, addr, ts); acesso a subpalavras desde M2.5 |
alu | witness | Aritmética em limbs de byte, deslocamentos, comparações; multiplicação e divisão RV32M desde M2.6 |
range | pré-processada · 256 linhas | Verificações de intervalo e a consulta de potências de dois |
nibble | pré-processada · 256 linhas | AND, OR, XOR de 4 bits; um acerto é, em si, uma verificação de intervalo nos dois operandos |
poseidon2 | witness | Uma linha por rodada de permutação em blocos de 32 linhas; atende o barramento POSEIDON2 e os dois digests |
input | witness · desde M4.1 | Uma linha por palavra de entrada privada; atende INPUT_DIGEST e INPUT_READ, de modo que uma leitura não escapa do compromisso |
keccak | witness · opcional | Keccak-f[1600] em blocos de 32 linhas, presente apenas em uma prova cujo guest chamou KECCAK (M4.2) |
Três conjuntos de restrições chegaram desde então. O conjunto 6 acrescentou uma tabela public obrigatória para a entrada pública de um programa definida no deploy, ligada ao digest sem sal H_PUB, e uma tabela opcional sha256 ao lado de keccak. O conjunto 7 (chain 16) cega todo terminal LogUp em um novo barramento BLIND e fixa um piso de 2⁷ linhas em toda tabela declarada, e acrescenta a syscall POSEIDON2_LEN, limitada por comprimento. O conjunto 8 (chain 18) acrescenta uma coluna GAS à tabela cpu e um valor público, o GAS_LIMIT declarado.
O que uma prova revela
Público: o hash de código hc (oito palavras de digest no circuito), o compromisso de entrada com sal H_IN (oito palavras), o tier de gas e oito palavras de saída. Desde o conjunto de restrições 6, também H_PUB, o digest da entrada pública, e desde o conjunto de restrições 8 o limite de gas declarado. O cabeçalho da prova declara as alturas das tabelas Keccak e SHA-256, então mostra se uma chamada fez hashing e, acima do piso de 2⁷, aproximadamente quanto.
Oculto: as entradas privadas (H_IN tem sal, então é ocultante além de vinculante); toda palavra de instrução, porque o verificador confere hc e nunca o programa; todo valor de registrador e de memória; todo desvio tomado; a contagem exata de ciclos e o gas exato usado; e quais syscalls rodaram, exceto pelo que as alturas das duas tabelas de hash mostram.
O tier é público em cada prova porque o tamanho de um STARK já revela a altura do seu traço; ocultar o índice não traria nada. hc é vinculante, não ocultante: veja onde ele para hoje.
Medido, no conjunto de restrições 5
| FRI | 80 consultas · 20 bits de PoW · blowup 8 · aridade 8 · ZK ativo; 260 bits conjecturados, cerca de 86 provados. O reajuste para 27 consultas do M2 foi revertido pela auditoria de 2026-09-12 |
| Chamada | private_payment no tier 10: cerca de 7 s para provar, cerca de 1,2 MB de prova com 80 consultas (435 KB com 27), abaixo de 21,6 s e 892 KB no M1 |
| Transferência | O guest de bundle 2-in-2-out das chains até a 13: 3.811 palavras, cerca de 9.160 ciclos, tier 14; cerca de 100 s para provar, cerca de 1,3 MB de prova. O guest de ativos ocultos 4-in-4-out da chain 14 está fixado no mesmo tier: cerca de 100 s, cerca de 1,42 MB |
| Verificação | Cerca de 16 ms com uma chave aquecida; a primeira verificação em uma nova chave (tier, alturas) leva cerca de 230 ms |
| Bloco | Orçamento de 4 MiB e teto de prova de 2 MiB: cerca de três transferências blindadas por bloco com 80 consultas |
Laptop Apple Silicon, build de release. A divisão em tabelas de bytes do M2.3 foi o que moveu o tempo de prova; o perfil de 80 consultas foi o que fez o tamanho da prova subir de novo. A chave do verificador independe do conteúdo do programa, sendo indexada pelo tier e pelas alturas de programa, entrada e keccak declaradas na prova, de modo que um nó aquece uma chave e a reutiliza.
Esses conjuntos posteriores mudaram os tamanhos. Sob o conjunto de restrições 7, uma prova de tier 10 tem 1.367.688 bytes no perfil de produção, e uma prova de tier 10 que carrega Keccak, 3.283.898 (medido em 2026-09-28). Desde a chain 17, uma transferência carrega duas provas: a prova do bundle de tier 14, de cerca de 1,49 MB, e a prova de autorização de tier 10, de cerca de 1,37 MB e cerca de 7 s para provar. O genesis da chain 20 define um bloco de 20 MiB e um limite de 4 MiB para a prova, e uma chamada não pode exceder o tier 14.
Três alvos, um circuito
Somente RISC-V executa nativamente. Programas Solidity e Solana ou rodam em um guest interpretador dentro da mesma relação, com o seu bytecode como entrada, ou são traduzidos fora da chain em programas RISC-V cujas saídas são idênticas às do interpretador, palavra por palavra. Os opcodes caros pedem tabelas de coprocessador dedicadas, em vez de simulação bit a bit.
| alvo | caminho | coprocessadores |
|---|---|---|
| RISC-V | Nativo. RV32IM, montado à mão por meio de asm.rs ou compilado em Rust no_std para riscv32im-unknown-none-elf, carregado como binário plano desde o M4.1, ou construído a partir de Rust ou C pelo rand-guest no contêiner de imagem (Implantar um programa em Rust) | Poseidon2 (e POSEIDON2_LEN desde o conjunto 7); Keccak-f[1600] desde o M4.2; SHA-256 desde o conjunto 6 |
| Solidity | solc --bin-runtime para bytecode EVM, depois o guest interpretador evm.bin (bytecode como entrada) ou o evm2rv, que traduz o bytecode para C que o rand-guest compila em uma imagem RV32IM com as mesmas saídas (O transpilador Ethereum) | Keccak-256 (tabela incluída), aritmética modular de 256 bits, ECRECOVER, syscalls de testemunha de Merkle para o armazenamento |
| Solana / SVM | um ELF sBPF, executado pelo guest interpretador sbpf.bin ou traduzido pelo sbpf2rv em uma imagem RV32IM com as mesmas saídas (O transpilador Solana) | SHA-256, verificação Ed25519, multiplicação de 64 bits |
Marcos
O marco 1 provou a máquina de uso geral. O marco 3 a transformou em um pool blindado: uma transferência com pertinência dentro do circuito é provada sob R_exec, e o verificador confere hc sem nunca ver uma palavra do programa. O marco 4 é compatibilidade: seu carregador, o compromisso de entrada e a tabela Keccak foram entregues como os conjuntos de restrições 4 e 5, e a tabela SHA-256 com o conjunto 6. Os guests interpretadores de EVM e sBPF, a toolchain rand-guest e os dois tradutores estão construídos. A transferência ERC-20 foi provada, em uma máquina de 128 GB; a prova do SPL Token, no tier 20, não. O marco 5 é a VM de recursão por trás da agregação de blocos, que está construída e desligada em todas as chains. Os conjuntos de restrições 7 e 8 vieram após as revisões de setembro e o modelo de gas.
| id | escopo | critério de saída | status |
|---|---|---|---|
| M1 | Cinco tabelas, ISA base RV32I, HALT/WRITE_OUTPUT/READ_INPUT, ZK ativado, preenchimento de tier, montador, emulador | fib, memcpy, bubble_sort, alu_mix e balance_check provam e verificam; todo teste de fraude é rejeitado | concluído. 44 testes; uma revisão posterior fechou cinco falhas de solidez em uma única leva |
| M1.5 | Chaves de visualização: um guest de transferência blindada de uma entrada e uma saída, envelopes de notas sob ML-KEM-768 e ChaCha20-Poly1305, divulgação com escopo de parte e de transação, um ledger simulado | Uma transferência prova no tier 12 e o ledger a aceita; cada escopo de divulgação abre exatamente as suas próprias linhas; uma chave de visualização não pode gastar | concluído. Não incorporado ao nó |
| M2 | Cache de chave do verificador, FRI reajustado para uma meta conjecturada de 100 bits, a tabela de bytes dividida em intervalo e nibble, loads e stores de subpalavra, a extensão RV32M | Entregue com escopo menor que o previsto: o carregador de binário plano e uma vinculação mais firme de READ_INPUT foram transferidos para o M4.1 | concluído. fib no tier 10: prova de 892 KB para 268 KB, 21,6 s para 3,1 s de prova, 2,17 s para 16 ms na primeira verificação. Conjunto de restrições 3, um hard fork |
| M3 | Chip e syscall Poseidon2; NOTE_COMMIT, NULLIFY e MERKLE_VERIFY como rotinas de guest sobre ele; o compromisso gasto retirado da saída pública; a tabela do programa como testemunha, com hc digerido dentro do circuito | A relação de transferência prova sob R_exec com pertinência dentro do circuito, e verify(hc, proof) nunca vê uma palavra do programa | concluído. Guest de transferência: 4.554 instruções, 4.903 ciclos, tier 14. O percurso de Merkle agora é um laço contado, de modo que o tamanho do programa já não cresce com a profundidade da árvore |
| CUDA | Backend de prover em GPU: NTTs e compromissos de Merkle Poseidon2 como kernels CUDA atrás dos traits Dft e Mmcs do Plonky3; rand send, call e deploy aceitam --cuda | Todo guest prova e verifica por meio do gêmeo de referência em Rust puro e do driver mock; o verificador em CPU não distingue os backends | concluído; primeira execução em hardware em 2026-09-28. Em uma NVIDIA H100, os kernels compilam para PTX em sm_80 e sm_90 e coincidem com a referência da CPU e do Plonky3. A remedição de produção em um nó de GPU da frota ainda está por fazer. Uma chamada CUDA não pode selar um envelope de entrada, porque o salt nunca sai do prover |
| M4.1 | O carregador de binário plano e os primeiros guests em Rust no_std compilados para riscv32im-unknown-none-elf; o compromisso de entrada com salt H_IN, com a sua própria tabela de entrada, de modo que READ_INPUT é uma consulta de lookup contra um vetor comprometido | Um guest construído pela toolchain padrão carrega, prova e verifica; duas leituras do mesmo índice de entrada concordam e as entradas estão vinculadas a H_IN | concluído. Entregue em 2026-09-11 como o conjunto de restrições 4: 26 valores públicos, oito tabelas, um hard fork |
| M4.2 | Uma tabela de coprocessador Keccak-f[1600] escrita à mão e a syscall KECCAK, presentes em uma prova apenas quando o guest as usou; altura de memória declarada na prova; uma chave de verificador indexada por quatro componentes; FRI de volta a 80 consultas após a auditoria de 2026-09-12 | keccak256 prova como um guest compilado, e uma prova sem a tabela tem exatamente o mesmo formato que uma do M4.1 | concluído. Entregue em 2026-09-12 como o conjunto de restrições 5, um hard fork. Uma prova com Keccak é cerca de 1,9 MB maior, acima do limite padrão de 2 MiB. Uma chain cujo genesis eleva o limite admite uma: a chain 13 (8 MiB) aceitou uma chamada de 3,41 MB com Keccak em 2026-09-19, e o limite da chain 20 é de 4 MiB |
| M4.3 · M4.4 | Guests interpretadores de EVM e sBPF compilados para RV32IM, com o bytecode estrangeiro como entrada; uma tabela de coprocessador SHA-256 ao lado da Keccak; depois a toolchain rand-guest e os tradutores evm2rv e sbpf2rv (2026-09-18) | Uma transferência ERC-20 e uma SPL Transfer são provadas, cada uma, sob R_exec | construído; uma prova de saída feita. evm.bin (18.009 palavras) e sbpf.bin (8.317) executam os vetores ERC-20 e SPL Token, e as imagens traduzidas coincidem com eles palavra por palavra. O transfer ERC-20 foi provado no tier 18 em um droplet de 128 GB em 2026-09-19 (pico de 85,0 GB, 53,8 min); a prova do SPL Token, no tier 20, é extrapolada em cerca de 330 GB e não foi feita (memória de prova). Nenhuma das duas é chamável na chain: uma chamada é limitada ao tier 14 |
| M5 | A VM de recursão (rVM): uma máquina nativa de Goldilocks com 24 instruções, cujos programas verificam provas do zkVM da Rand, um programa de agregação genérico em N por formato de prova interna, uma divisão de backend em CPU e CUDA, e um autoverificador (M5.1 a M5.4, 2026-09-13 a 2026-09-16) | 50 provas reais de bundle de produção aceitas e 50 adulteradas recusadas na etapa indicada; uma prova rVM do programa verificador sobre uma prova real de bundle verifica nativamente (perfil de teste) | construído; provas de produção exigem uma máquina grande. Incorporado como crates/randprotocol-rvm. A agregação do lado da chain está integrada e desligada em todas as chains (abaixo) |
| set 7 | Todo terminal LogUp ofuscado; toda tabela declarada com piso de 2⁷ linhas; verificações de intervalo de 32 bits em palavras de entrada, públicas e de salt; a syscall POSEIDON2_LEN; uma correção de JALR; chaves de verificador com salt a partir de key_derivation_v2 | As correções das revisões do zkVM de 2026-09-27 e 28 que movem uma chave de verificador, feitas em um único corte | concluído. Fullnode v0.6.1, chain 16 (2026-09-28), um hard fork |
| set 8 | O medidor de gas: uma coluna GAS na tabela cpu e um GAS_LIMIT público, com GAS ≤ GAS_LIMIT provado dentro do circuito; o gas exato da execução permanece privado | Uma chamada paga pelo limite que declara, e toda prova de bundle declara o mesmo limite fixado | concluído. Fullnode v0.6.7-rc1, chain 18 (2026-09-29), um hard fork. bundle_gas_limit é 20.479 |
Fases do pool blindado
O ledger do fullnode chegou em três fases, cada uma um hard fork (docs/shielded.md §7). A S1 substituiu o ledger de contas por um pool de notas; a S3 trouxe a bridge de volta como notas e foi entregue primeiro; a S2 colocou o staking por cima. As três estão na main e na chain atual.
As linhas abaixo de S2 são o trabalho da v0.5. Cada linha é um hard fork. Foram reunidas numa única chain nova, a chain 14, criada em 2026-09-20 a partir do build b3c594c e marcada como v0.5 no mesmo dia, depois de uma viagem de ida e volta de zUSD ao vivo pelos endpoints de origem implantados. A chain 15, ativa desde 2026-09-26 na v0.5.8 e posteriores, levou tudo isso, com as correções das auditorias v4 e v5 condicionadas ao genesis ativadas: um faucet com lista de permissões e orçamento por época, ativação de bond com atraso, um limite para o peso de stake, registros vinculados ao genesis, consensus_domain 1, as regras de bridge v2 e o limite do registro de tokens, taxa de registro queimada e limite de 2⁶³ para notas. A chain 20, ativa desde 2026-10-01 06:17 UTC na v0.6.8 (c9c9bd3c), um hard fork da chain 19, mantém tudo isso e acrescenta o trabalho das versões v0.6, listado abaixo.
| id | escopo | critério de saída | status |
|---|---|---|---|
| S1 | O pool em si: notas, pacotes provados de 2 entradas e 2 saídas, uma árvore de compromissos Poseidon2 de profundidade 32 e o conjunto de nullifiers, a wallet rand com um prover local, o RPC redigido | Uma transferência blindada entre wallets, uma corrida de gasto duplo entre dois validators e um deploy-and-call pago por pacotes passam na suíte do cluster | concluído. Ativo na frota pública desde a chain 6 (2026-09-12) |
| S3 | A bridge como notas: um ativo bridged carrega o índice do ativo no registro, uma attestation deposita uma nota que a própria chain calcula, BridgeBurn é a única transação de dois pacotes; envelopes selados para as entradas de chamadas, abríveis pelo chamador, por uma chave por chamada ou por um auditor nomeado | Um ativo bridged é cunhado, gasto e queimado como nota; um chamador pode divulgar com o que um programa foi executado sem publicá-lo, e rand open-call confere a abertura contra H_IN | concluído. Foi o primeiro a entrar. As chains 9 a 13 deixaram a seção da bridge fora do genesis; toda chain desde a 14 a inclui. Desde a chain 14 uma queima é um único pacote, não dois |
| S2 | Staking na chain blindada: um registro público de validators, Bond a partir da queima de um pacote, Unbond ao longo de duas épocas, Withdraw para uma nota num endereço de pagamento, épocas de 1.000 blocos que rederivam o conjunto, e uma auditoria de supply sobre o registro e o pool | Um quinto validator se registra, faz bond e propõe a partir da época seguinte; outro faz unbond para fora do conjunto e faz withdraw para uma nota que sua wallet de pagamento gasta; ambos passam na suíte do cluster | concluído. A árvore local de compromissos da wallet veio depois, em 2026-09-21: a wallet calcula suas próprias witnesses e já não informa ao seu nó qual folha ela gasta |
| RPL | O padrão de tokens (docs/tokens.md): um token é uma entrada de registro no ledger com um id bech32m rpl1… de 62 caracteres; a criação é sem permissão, mediante uma taxa de registro em RAND; a autoridade de mint é fixada no registro como nenhuma, uma chave ou a bridge; os símbolos não são únicos; rand token create, mint, set-authority, burn, info, list, e rand_getTokens, rand_getToken, rand_getTokenSupply | Um token é registrado, cunhado, enviado com rand send --asset e queimado como notas no mesmo pool | em execução desde a chain 14 (v0.5). Na chain 20 a taxa de registro é 1 RAND, queimado, o registro comporta no máximo 4.096 tokens, e o genesis lista zUSD no índice 1 |
| RPL-2 | Estado de programa (docs/program-state.md): células por programa (uma chave de 8 palavras para um valor de 8 palavras, na raiz de estado), um vault público por ativo, um token cunhado apenas pelo seu programa, e a ação Invoke (Action 33), uma chamada que declara as células que lê e escreve e as notas que paga; rand program invoke, state, vault, e rand_getProgramCell, rand_getProgramCells, rand_getProgramVault | O ledger aplica uma transição somente se toda leitura declarada ainda for válida e o vault cobrir todo pagamento; uma leitura obsoleta é recusada e provada de novo | em execução desde a chain 20 (v0.6.8). cell_fee de 0,01 RAND por célula criada; no máximo 8 leituras, 8 escritas e 4 pagamentos por invoke. Veja Programas |
| pacote de ativo oculto | Toda transação carrega exatamente um pacote de 4 entradas e 4 saídas no lugar do de 2 entradas e 2 saídas: os slots 0–1 guardam o ativo privado (dummies numa transferência apenas de RAND), os slots 2–3 são sempre RAND e pagam a taxa. A transferência de token em dois pacotes e a queima de bridge em dois pacotes deixam de existir | Uma transferência de RAND e uma transferência de qualquer token RPL publicam exatamente o mesmo formato, de modo que o ativo movimentado fica oculto | em execução desde a chain 14 (v0.5). Tier 14, cerca de 100 s para provar, cerca de 1,42 MB de prova nas chains 14 e 15; hc_bundle 83d3a370… nelas. As chains 18 a 20 fixam o bundle guest v3, hc_bundle 60af094a…, cerca de 1,49 MB |
| vinculação da transação | Toda prova de pacote é feita sobre, e verificada contra, H("rand-tx-bind-1", chain_id ‖ tx with proofs blanked), carregado no segmento de entradas públicas | Uma prova copiada, sem modificação, reenviada com destino, validator ou memo alterados é recusada | em execução desde a chain 14 (v0.5). Desde a chain 20 (binding_domain 1) a pré-imagem é H("rand-tx-bind-2", genesis hash ‖ chain_id ‖ …), e toda mensagem de ação assinada também carrega o hash do genesis, de modo que nada provado ou assinado para uma chain é verificado em outra |
| B1–B4 | Endurecimento da bridge (docs/bridge.md §§14–20). B1: um limite diário de mint por backing e uma chave de pausa que só pode pausar (despausar exige o quórum PQ). B2: um timestamp de bloco mais de 60 s à frente do de seu pai é inválido, e um validator não vota em um bloco mais de 15 s à frente do seu relógio, portanto os validators precisam de NTP. B3: um quórum de co-assinaturas Dilithium2 em todo mint. B4: listar um token bridged ou um backing após o genesis sob o quórum de guardiões PQ, sem corte de chain | zUSD, um token com sete backings (USDT e USDC na Ethereum, Binance Smart Chain, Tron e Solana), é registrado por transação, e total_supply == Σ backings.locked vale por construção. O gate local de nove fases (zusd_e2e.rs: quatro validators, provas reais, faucet, registro, depósito, transferência, queima e auditoria) passou 9 de 9 | em execução desde a chain 14 (v0.5). Na chain 20: limite de mint de 100.000 zUSD por dia por backing mais um global de 4.000 zUSD por 24 horas móveis (regras de bridge v2), conjunto de guardiões 1 com oito guardiões PQ, uma taxa de 10 bps em zUSD sobre cada mint e cada queima (bridge.fees), e rotações de guardiões que exigem posse e aguardam 86.400 s (bridge.rotation). zUSD está listado no genesis da chain 20 com seus sete backings e os 99 zUSD bloqueados no corte |
| auditoria v3 | As correções da terceira rodada de auditoria interna, liderada por um cofundador (2026-09-19; nenhuma auditoria independente foi realizada). POOL-1: um Mint de faucet carrega a abertura de sua nota (pk, time, r), a admissão recalcula o compromisso, e o minter assina rand-mint-2; as notas de alocação do genesis também carregam uma abertura. RPC-1: rand_getWitness(es) executa no máximo duas reconstruções de árvore ao mesmo tempo e responde -32000 busy após 10 s. OPS-1: todas as dezoito chaves de validators foram rotacionadas, geradas fora do repositório, e nenhuma chave é rastreada no repositório | Um mint cujo compromisso abre para mais que seu valor é recusado; nenhuma chave da chain 14 jamais esteve no repositório | em execução desde a chain 14 (v0.5). PRIV-1, a requisição de witness que nomeia a folha, foi encerrada em 2026-09-21 pela árvore própria da wallet |
Versões desde a v0.5
Toda versão é uma tag do git com uma entrada no CHANGELOG.md do fullnode. Uma versão que altera o consenso, o formato de wire ou uma chave do verifier sai com uma nova chain; as demais entram na chain ativa um nó por vez.
| versão | o que trouxe | cadeia |
|---|---|---|
| v0.5 a v0.5.8 | Tokens RPL, zUSD e a bridge reforçada (acima); as correções da auditoria; poda do histórico; reforço do consenso e da sincronização | 14, 15 |
| v0.5.9 | Correções de rescan: o faucet só emite a partir de validadores da gênese, back-off na sincronização, pré-verificações no gossip | 15 |
| v0.5.10 | Compartilhamento de endereços: fingerprints, links randpay: e códigos QR; o memo cifrado, ativado pela primeira vez na cadeia 18 | 15 |
| v0.5.11 | Vesting com bloqueio temporal na gênese para alocações de equipe, investidores e parceiros. Condicionado à gênese e ativo em nenhuma cadeia | nenhuma |
| v0.6 | As correções de zkVM, rVM e agregação das revisões de setembro | 15 |
| v0.6.1 | Conjunto de restrições 7: blinding de LogUp, piso de 2⁷ para as tabelas, verificações de intervalo de 32 bits, POSEIDON2_LEN, a correção de JALR. A cadeia 16 foi criada com hardening_v6 e o guest de bundle v2 | 16 |
| v0.6.2 | Prova delegada, fase 1: o binário rand-prover e o --prover da carteira. Um provador da fase 1 recebe a chave de gasto | 16 |
| v0.6.3, v0.6.4 | Prova delegada, fase 2: autorização dividida. A prova do bundle deixa de receber a chave de gasto; quem a recebe é uma prova de autorização de nível 10, e o domínio do id da transação passa a ser rand-txid-3 | 17 |
| v0.6.6, v0.6.7-rc1 | Gas: conjunto de restrições 8, um limite de gas declarado por prova, gas dinâmico e preços por byte; o memo ativado. A v0.6.6 nunca chegou a ser publicada com tag | 18 |
| v0.6.7 | Correções na cadeia 18 que não alteram nenhuma regra de consenso: poda de provas seladas (dormente), fixação do formato do envelope, higiene da chave de visualização, o alocador da rVM, aliasing em kernels de GPU, cobertura de testes da ALU. Recebeu a tag antes de a suíte completa do workspace terminar | 18, 19 |
| v0.6.8 | RPL-2: células de programa, cofres de programa e a ação Invoke. Taxas de bridge do zUSD, nos dois sentidos. As últimas correções da audit-v6: nenhuma liberação automática de bloqueio (CON-4) e um pacemaker com certificado de timeout (CH-1); um listener --public-rpc, limites de leitura, peers validadores reservados, orçamentos de sincronização e de gossip, o limite de bytes do pool, um limite para o grau declarado no cabeçalho de uma prova (ZKV-4); e as regras condicionadas à gênese que a cadeia 20 ativa: a vinculação ao hash da gênese, testnet, uma janela de prova de 1.024 blocos, tetos de preço do gas e a carga de bytes pagante, admissão por voto, o limite de entrada de stake como fração, posse e um atraso para as rotações da bridge. As carteiras precisam desta build para enviar na cadeia 20 | 20 |
Onde para hoje
Desvios em relação ao whitepaper, declarados em vez de suavizados. Cada um é acompanhado na documentação do próprio crate, com o marco que o encerra.
hcé vinculante, mas não ocultante: não carrega salt, de modo que um programa adivinhado pode ser confirmado e duas implantações do mesmo programa podem ser associadas. O que o M3.4 eliminou foi o verificador manter o programa inteiro em claro.- Uma carteira compilada antes de 2026-09-21 pede testemunhas ao seu nó, e o pedido de testemunha nomeia a folha que está prestes a ser gasta. Um
randatual mantém a própria cópia da árvore e nunca pede; o nó ainda atenderand_getWitnesspara as carteiras mais antigas. - Os depósitos são públicos na fronteira: uma emissão do faucet, uma nota da gênese e um depósito pela bridge carregam o valor em claro (desde a cadeia 14, uma emissão e uma nota da gênese também carregam a sua abertura, de modo que a chave do proprietário também é pública), a mesma visibilidade de um salto que um depósito de transparente para blindado tem em qualquer lugar.
- O conhecimento zero é estatístico, não perfeito. Essa é a propriedade que o FRI com hiding do Plonky3 0.7 de fato oferece, e o crate o declara.
- O hash da transcrição é Poseidon2 com constantes de rodada de desenvolvimento, não o SHA3-384 / BLAKE3-384 dos papers. Uma troca de configuração, não uma reescrita.
- Com 80 consultas FRI, uma prova de bundle tinha cerca de 1,42 MB nas cadeias 14 e 15 (cerca de 1,3 MB até a cadeia 13). Desde a cadeia 17, uma transferência carrega cerca de 2,85 MB de prova: a prova do bundle, com cerca de 1,49 MB, e a prova de autorização, com cerca de 1,37 MB. Em uma cadeia padrão, com blocos de 4 MiB e um teto de prova de 2 MiB, uma prova que contém Keccak excede o teto de prova de imediato; a gênese da cadeia 20 define blocos de 20 MiB e um teto de prova de 4 MiB (as cadeias 13 a 16 definem 8 MiB).
- O cabeçalho de uma prova de chamada não é ocultado. Ele declara o nível e as alturas das tabelas de Keccak e de SHA-256, e portanto mostra se a chamada fez hash. Chamadas confirmadas na cadeia 15 antes do piso do provador da v0.6 expuseram mais: uma tabela privada com menos de 2⁷ linhas podia ser lida a partir da prova. O piso do provador da v0.6 encerrou isso para as novas chamadas, e o conjunto de restrições 7 com
hardening_v6o tornou uma regra da cadeia a partir da cadeia 16. - Uma chamada é limitada ao nível 14, com no máximo 2¹² linhas de Keccak (128 permutações) e 2¹³ linhas de SHA-256 (128 compressões), e, sob
hardening_v6, um programa com mais de 8.180 palavras não pode ser implantado. Os guests interpretadores de EVM e sBPF e as imagens traduzidas de ERC-20 e SPL Token estão todos acima desse limite. - Quem detém a testemunha vê tudo. O ZK protege a visão do verificador, não a do provador. Desde a cadeia 17, uma carteira pode entregar a prova do bundle a um
rand-proverpareado sem entregar a chave de gasto, mas esse provador ainda detém a chave de visualização e vê as notas. O backend CUDA rodou pela primeira vez em hardware em 2026-09-28 e ainda não tem medição em produção.
Estrutura do repositório
O workspace Cargo do fullnode, como disposto em seu README e em seu diretório crates/.
| caminho | o que contém |
|---|---|
crates/randprotocol-core/ | Lógica pura, sem E/S: criptografia, notas e a árvore de compromissos, regras do ledger, gas, gênese, a máquina de estados do HotStuff |
crates/randprotocol-zkvm/ | A zkVM da Rand, importada de zkp-circuits/research no conjunto de restrições 8 (circuits aeacf31; ressincronizada com deploy/sync-zkvm.sh), mais o verificador de provas do lado da cadeia e seu cache de chaves de verificação |
crates/randprotocol-rvm/ | A VM de recursão, importada de zkp-circuits/recursion: uma máquina nativa de campo cujos programas verificam provas da zkVM da Rand |
crates/bridge-codec/ | O formato de transmissão e a regra de quórum da bridge de guardiões, compartilhados byte a byte com os contratos Solidity e o programa Solana |
crates/randprotocol-node/ | Armazenamento RocksDB, rede libp2p, mempool, sincronização de blocos, o servidor JSON-RPC e o binário rand-node |
crates/randprotocol-client/ | O binário de carteira rand e a biblioteca RpcClient, sem dependência de RocksDB nem de libp2p |
crates/randprotocol-prover/ | O binário rand-prover: um provador delegado que gera provas de bundles para carteiras pareadas |
deploy/ | Arquivos de gênese da testnet, nodes.env, scripts de execução, provisionamento em nuvem, scripts de cut-over e de reconstrução. Nenhuma chave é versionada aqui desde a preparação da cadeia 14 |
docs/ | Documentação de referência e a especificação de design |
scripts/ | Testnet local com dois validadores |
Especificado, ainda não entregue
Estes componentes são descritos nos papers ou na documentação do fullnode, mas não estão em execução: ou estão ausentes dos repositórios, ou foram construídos e não estão ativados em nenhuma cadeia. Eles são listados para que a distância entre a especificação e o código seja legível, e não inferida.
| componente | situação |
|---|---|
| bridge · guardian | Os daemons de guardião e de relayer que executam o formato de atestação de ponta a ponta; os contratos, o codec e a metade receptora do fullnode estão entregues, os daemons não |
| fullnode · aggregation | Agregação de blocos com a VM de recursão: selagem, poda e sincronização em forma selada. Construída e desativada em todas as cadeias; o rand-node recusa uma gênese com uma seção aggregation. Ainda falta o exercício de ponta a ponta com agregado forjado, e ela remove apenas a prova do bundle, não a prova de autorização. As provas de produção da rVM exigem uma máquina grande: no conjunto de restrições 7, um agregado de duas levou 133 GB, de três 221 GB, e a prova de saída mais de 256 GB (medido em 2026-09-28 e 29; não remedido no conjunto de restrições 8) |
| fullnode · vesting | Alocações da gênese com bloqueio temporal para equipe, investidores e parceiros (v0.5.11, docs/vesting.md). Condicionado à gênese: sem uma seção vesting, as quatro ações de vesting são recusadas, e nenhuma cadeia tem uma. A auditoria de oferta da cadeia 20 reporta todos os contadores de vesting como zero. Desde a v0.6.8, uma entrada revogável é revogada por um limiar de seus revogadores, e somente para a tesouraria que a sua entrada na gênese nomeia |
| fullnode · slashing | Slashing e jailing por equivocação do líder estão construídos na v0.6.8 sob staking.slashing e desativados na cadeia 20 (sua gênese não tem essa seção, e as 26 chaves de validador pertencem a um único operador). Recompensas de bloco, o beacon de líder por sortição de hash, um acumulador de nullifiers e chamadas entre programas não estão construídos. O estado persistente por programa foi entregue como RPL-2 (acima) |
prover/ | Daemon de prova em GPU: reivindica lotes da fila, disputa a submissão. Os kernels CUDA ficam em zkp-circuits e rodaram pela primeira vez em uma NVIDIA H100 em 2026-09-28; o daemon de mercado não existe. O rand-prover, que está entregue, gera provas para as carteiras pareadas a ele e não é um mercado |
| zkp-circuits · prova de saída M4.4 | Uma prova de uma transferência SPL Token (nível 20), extrapolada em cerca de 330 GB. A transferência ERC-20 (nível 18) foi provada em um droplet de 128 GB em 2026-09-19. Nenhuma das duas pode ser chamada na cadeia 20, que limita uma chamada ao nível 14 |
Compilar e testar
Fluxo de trabalho padrão em Rust em cada repositório. O fullnode é um único workspace do Cargo com uma toolchain fixada e uma suíte de testes de cluster que inicia nós reais sobre TCP. Sua compilação exige o repositório de circuitos (circuits) clonado ao lado, em um diretório chamado circuits, no commit a partir do qual as crates vendorizadas foram sincronizadas (aeacf31 para v0.6.7 e v0.6.8). A zkVM é uma crate independente em zkp-circuits, com sua própria toolchain fixada e uma demonstração que narra o que uma chamada confidencial revela e o que não revela.
O fullnode:
git clone https://github.com/randprotocol/fullnode.git
git clone https://github.com/randprotocol/zkp-circuits.git circuits # the sibling directory must be named circuits
git -C circuits checkout "$(sed -n 's/^circuits: //p' fullnode/crates/randprotocol-zkvm/guests-compiled/PROVENANCE.md)"
cd fullnode
# Rust 1.98.1 is pinned by rust-toolchain.toml; first build pulls RocksDB and Plonky3, 10 to 20 minutes
cargo build --release # target/release/rand-node, target/release/rand, target/release/rand-prover
# All crates; release because STARK proving is slow in debug. One to two hours, mostly proving
cargo test --release
# One machine, two validators
scripts/local-testnet.sh
target/release/rand --rpc http://127.0.0.1:8545 status
A zkVM de pesquisa, em zkp-circuits/research:
# Toolchain is pinned by rust-toolchain.toml; the first build pulls Plonky3
cargo build --release
# Narrated demo: thirteen proofs, one at production FRI parameters (~6-7 min)
cargo run --release
# Emulator, per-table constraints, cheating provers, ZK, end-to-end, viewing keys, compiled guests (395 tests, ~17 min)
cargo test
A suíte do fullnode, medida na v0.6.1 em uma máquina de 16 vCPUs: core com 521 testes, node com 373, client com 117, a suíte do prover trapaceiro com 116, as trapaças de bundles ocultos com 21 (75 min), o fluxo da carteira com 6 (53 min), o cluster com 26 (44 min) e o portão de ponta a ponta da zUSD com 2 (51 min). As provas de produção da VM de recursão ficam fora dela e exigem a memória listada acima.
Running a node explica como ingressar na testnet pública com a compilação; o genesis da testnet, os peers de bootstrap e os scripts de execução acompanham o diretório deploy/ do fullnode, e a página de download traz a versão resumida.
Contribute
O fullnode é licenciado sob a GNU General Public License v3.0 (GPL-3.0-only); antes, era Apache-2.0. Abra issues para bugs e propostas de design no repositório que a mudança afeta. Pull requests são bem-vindos: execute cargo fmt && cargo clippy antes de enviar e mantenha as mudanças restritas ao escopo. As issues do fullnode são o lugar para começar.
A arquitetura, o circuito de privacidade, a prova do token de taxa e o compromisso (tradeoff) pós-quântico estão todos documentados no whitepaper, na página de papers. O diretório docs/ do próprio repositório do fullnode é a fonte com a qual todas as páginas desta documentação são conferidas.