Adicione assinatura clara ao seu protocolo com o ERC-7730
A maioria das grandes explorações no Ethereum teve a mesma etapa final: um usuário aprovando uma transação que não conseguia entender de forma significativa. Carteiras de hardware mostram dados de chamada (calldata) em formato hexadecimal bruto e, pior ainda, forçam você a manter a assinatura cega ativada. Carteiras de software mostram campos decodificados, mas apenas quando reconhecem o contrato. Quando não reconhecem, seja porque o protocolo é novo, o aplicativo está comprometido ou o dispositivo está offline, os usuários assinam às cegas.
O ERC-7730 (opens in a new tab) define um formato JSON padrão para descrever o que as chamadas de função do seu contrato significam.
Uma carteira que suporta o ERC-7730 lê o seu descritor e mostra:
Swap
Enviar: 1.000 USDC
Receber no mínimo: 0,42 WETH
Protocolo: Uniswap V3
Ou uma única frase construída, legível tanto por humanos quanto por agentes:
Trocar 1.000 USDC por pelo menos 0,42 WETH
Em vez de um seletor de função e uma lista de valores inteiros brutos.
Isso é a assinatura clara (opens in a new tab) — "O que você vê é o que você assina" (What You See Is What You Sign). Este tutorial orienta você na escrita de um descritor para o seu próprio contrato, na validação dele com a ferramenta CLI oficial e no envio para o registro aberto.
Pré-requisitos
- Familiaridade com Solidity e ABIs de contratos inteligentes
- Um contrato inteligente implantado com uma ABI verificada (a verificação no Sourcify (opens in a new tab) é exigida antes que um descritor seja aceito no registro)
- Python 3.12+ para a CLI de validação
- Conhecimento básico de JSON
O que é um descritor ERC-7730?
Um descritor é um único arquivo JSON com três seções:
| Seção | Propósito |
|---|---|
context | Vincula o descritor a implantações de contratos específicos por ID da cadeia (chain ID) e endereço |
metadata | Nomeia o projeto e define constantes reutilizáveis |
display | Mapeia cada assinatura de função para rótulos legíveis por humanos e formatos de campo |
Como o descritor é separado do próprio contrato, você pode adicionar suporte à assinatura clara a qualquer protocolo existente sem precisar de uma nova implantação. As carteiras recuperam os descritores do registro e os utilizam no momento da assinatura.
Passo 1: Criar o esqueleto do arquivo
Crie um arquivo chamado calldata-<contractname>-<descriptorversion>.json. O prefixo calldata- informa ao registro que este descritor cobre chamadas de função de contrato, em oposição a eip712- para mensagens de dados tipados. O descriptorversion informa ao registro a versão do arquivo do descritor, sendo 0 por padrão se nenhuma versão for fornecida.
{
"$schema": "https://eips.ethereum.org/assets/eip-7730/erc7730-v2.schema.json",
"context": {},
"metadata": {},
"display": {
"formats": {}
}
}
Passo 2: Escrever a seção de contexto
A seção context vincula o descritor a uma ou mais implantações de contrato. As carteiras usam isso para corresponder uma transação recebida ao descritor correto.
"context": {
"$id": "uniswap-v3-router-mainnet",
"contract": {
"deployments": [
{ "chainId": 1, "address": "0xYourContractAddressOnMainnet" },
{ "chainId": 137, "address": "0xYourContractAddressOnPolygon" }
]
}
}
Campos de contexto
context.$id— Um identificador exclusivo para este documento descritor ou configuração de implantação.contract.deployments— O conjunto de implantações ao qual este descritor se aplica.deployments[].chainId— O ID da cadeia (chain ID) EVM para uma implantação. Inclua todas as cadeias onde seu contrato está implantado.deployments[].address— O endereço do contrato que as carteiras devem associar a este descritor. Use o endereço de implementação que contém a lógica de execução.
Passo 3: Escrever a seção de metadados
A seção de metadados fornece informações legíveis por humanos sobre o projeto e o contrato descritos por este arquivo. As carteiras podem usar essas informações para exibir nomes de protocolos, links e outros detalhes contextuais durante a assinatura.
"metadata": {
"owner": "Example Swap Protocol",
"info": { "url": "https://example.xyz" },
"contractName": "SwapRouter"
}
Campos de metadados
owner— O projeto, protocolo, organização ou mantenedor responsável por este descritor.info.url— Uma URL canônica do projeto ou da documentação que as carteiras podem exibir aos usuários para contexto adicional.contractName— O nome do contrato ou da implementação descrito por este arquivo, geralmente correspondendo ao código-fonte verificado ou à ABI.
Se o seu arquivo ERC-7730 descreve um contrato ERC-20, você também deve adicionar um objeto de token.
Passo 4: Escrever a seção de formatos de exibição
O objeto display.formats mapeia assinaturas de função para instruções de assinatura legíveis por humanos. É assim que as carteiras mostram sua função aos usuários antes que eles aprovem uma transação!
Cada chave é um fragmento de ABI legível por humanos — a assinatura da função, incluindo os nomes e os tipos dos parâmetros exatamente como aparecem na sua ABI.
Exemplo: Descrevendo um swap de token
"display": {
"formats": {
"swapExactTokensForTokens(uint256 amountIn,uint256 amountOutMin,address[] path,address to,uint256 deadline)": {
"intent": "Swap",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMin}",
"fields": [
{
"path": "#.amountIn",
"label": "Send",
"format": "tokenAmount",
"params": {
"tokenPath": "#.path[0]"
}
},
{
"path": "#.amountOutMin",
"label": "Receive minimum",
"format": "tokenAmount",
"params": {
"tokenPath": "#.path[1]"
}
},
{
"path": "#.to",
"label": "Recipient",
"format": "addressName",
"params": {
"types": ["eoa", "contract"],
"sources": ["local", "ens"]
}
},
{
"path": "#.deadline",
"label": "Expires",
"format": "date",
"params": {
"encoding": "timestamp"
}
}
]
}
}
}
Campos de exibição
intent— (Obrigatório) Uma descrição curta e amigável da ação, como "Swap".interpolatedIntent— (Recomendado) Um modelo de frase mais rico que incorpora valores de campo formatados, como"Swap {amountIn} for at least {amountOutMin}". Inclua isso junto comintentpara fornecer um descritor ainda mais amigável que as carteiras podem escolher exibir, dadas quaisquer restrições de exibição.fields— (Obrigatório) A lista ordenada de campos de transação que as carteiras devem exibir aos usuários.-
path— (Obrigatório) Uma referência aos dados da transação.#.fieldNameaponta para um parâmetro de dados de chamada (calldata) decodificado pelo nome na ABI.@.valuerefere-se ao valor em ETH enviado com a transação. -
label— (Obrigatório) O rótulo legível por humanos mostrado ao lado do valor. -
format— (Recomendado) Controla como o valor deve ser renderizado. Formatos comuns incluem:tokenAmountaddressNamedate
Use
rawquando nenhuma formatação adicional for necessária. Alguns formatos aceitam configurações adicionais emparams. Por exemplo:tokenAmountpode usartokenPathpara identificar qual endereço de token fornece os metadados de decimais e ticker.datepode usarencodingpara descrever como o carimbo de data/hora (timestamp) é codificado.
Se o formato selecionado não exigir informações extras, omita
params.
-
O descritor completo
{
"$schema": "https://eips.ethereum.org/assets/eip-7730/erc7730-v2.schema.json",
"context": {
"$id": "uniswap-v3-router-mainnet",
"contract": {
"deployments": [
{
"chainId": 1,
"address": "0xYourContractAddressOnMainnet"
},
{
"chainId": 137,
"address": "0xYourContractAddressOnPolygon"
}
]
}
},
"metadata": {
"owner": "Example Swap Protocol",
"info": {
"url": "https://example.xyz"
},
"contractName": "SwapRouter"
},
"display": {
"formats": {
"swapExactTokensForTokens(uint256 amountIn,uint256 amountOutMin,address[] path,address to,uint256 deadline)": {
"intent": "Swap",
"interpolatedIntent": "Swap {amountIn} for at least {amountOutMin}",
"fields": [
{
"path": "#.amountIn",
"label": "Send",
"format": "tokenAmount",
"params": {
"tokenPath": "#.path[0]"
}
},
{
"path": "#.amountOutMin",
"label": "Receive minimum",
"format": "tokenAmount",
"params": {
"tokenPath": "#.path[1]"
}
},
{
"path": "#.to",
"label": "Recipient",
"format": "addressName",
"params": {
"types": ["eoa", "contract"],
"sources": ["local", "ens"]
}
},
{
"path": "#.deadline",
"label": "Expires",
"format": "date",
"params": {
"encoding": "timestamp"
}
}
]
}
}
}
}
Passo 5: Enviar para o registro
O registro ERC-7730 (opens in a new tab) é um repositório aberto hospedado pela Fundação Ethereum como uma administradora neutra. Qualquer pessoa é livre para cloná-lo e hospedá-lo por conta própria — as carteiras decidem de forma independente em quais instâncias de registro confiam.
- Faça um fork (bifurcação) do repositório no GitHub
- Crie uma pasta em
registry/<your-project-name>/ - Coloque seu arquivo dentro dela:
registry/myproject/calldata-mycontract-0_0.json - Atualize o campo
$schemapara o caminho relativo usado dentro do repositório:"../../specs/erc7730-v2.schema.json" - Abra um pull request
Quando você abre o PR, a CI executa automaticamente a validação do esquema, verifica se as assinaturas de função produzem seletores válidos, confirma se o endereço do contrato está verificado no Sourcify e sinaliza inconsistências na ABI. Os resultados da verificação aparecem diretamente no PR. Os mantenedores do registro analisam os envios em busca de descritores malformados ou potencialmente maliciosos. A inclusão no registro não implica auditoria ou endosso.
O que acontece após a mesclagem?
Todos os descritores no registro estão abertos a auditores. Após a mesclagem do seu PR, qualquer auditor pode revisar seu descritor e publicar uma atestação criptográfica (sob o ERC-8176 (opens in a new tab)) confirmando sua precisão.
Esses sinais de atestação permitem que as carteiras apliquem suas próprias políticas de confiança — um descritor com várias atestações independentes tem mais peso do que um sem nenhuma. Você pode entrar em contato com a comunidade de auditores através do clearsigning.org (opens in a new tab).
As carteiras escolhem qual registro irão suportar. Assim que seu descritor estiver no registro, as carteiras que suportam o ERC-7730 começarão a buscá-lo, caso esteja em seu registro, e exibirão dados legíveis por humanos quando os usuários interagirem com seu contrato.
Leitura adicional
- Especificação do ERC-7730 (opens in a new tab)
- Registro ERC-7730 (opens in a new tab)
- clearsigning.org (opens in a new tab) — ferramentas, status do ecossistema e governança
- Verificação de contrato no Sourcify (opens in a new tab)
- Iniciativa Trillion Dollar Security (opens in a new tab)
Última atualização da página: 12 de maio de 2026