Escrever regras de política de transação

Nesta página, descrevemos os atributos que uma política de transação pode verificar e mostramos exemplos de regras para transações do Ethereum (ETHEREUM_TX_V2 e EIP712_TYPED_DATA_V1), Bitcoin (BITCOIN_TX_V2) e Solana (SOLANA_TX_V1).

Para saber como as políticas são combinadas, quais são aplicadas e por que uma transação é negada, consulte Avaliação da política de transações.

Estrutura da regra

Uma política de transação é uma única instrução permit ou forbid do Cedar sobre o principal, a ação, o recurso e o contexto:

permit (
  principal,
  action == Action::"buy_transaction",
  resource == Resource::"transaction_management"
)
when {
  context.principal_keyring == "institutional-treasury" &&
  context.schema == "ETHEREUM_TX_V2" &&
  context has amount_token_scaled && context.amount_token_scaled <= 1000000000
};

Lembre-se:

  • Os atributos estão no nível superior do contexto. Escreva context.amount_token_scaled, não context.transaction.spend_amount_scaled, como em v1alpha1.
  • Alguns atributos são opcionais. Um atributo opcional que não está no contexto faz com que a política não seja avaliada, e uma política que não é avaliada não corresponde. Verifique se há um atributo opcional com has antes de ler ou com unless { context has ... } em uma regra forbid. Para mais informações, consulte o Cenário 6 e o Cenário 8.
  • As strings do Cedar diferenciam maiúsculas de minúsculas. Compare os endereços no formato descrito na tabela de cada rede.

Para o principal, consulte A solicitação do Cedar. Para as ações aceitas por CreateTransaction (buy_transaction, sell_transaction e internal_transfer_transaction), consulte Ação e recurso.

Atributos de contexto

O contexto de cada transação tem os atributos decodificados do payload, os IDs da chave de assinatura e do KeyRing, além dos atributos de metadados (fiat_amount, validity, principal_value1 e principal_value2) que o iniciador define.

Os atributos de payload são os mesmos para todos os blockchains. A tabela a seguir descreve todos os atributos de contexto, e as tabelas para Ethereum, Bitcoin e Solana descrevem como a computação multipartidária preenche cada atributo para esse blockchain:

Atributo Tipo Cedar Sempre presente? Valor
schema String Sim O formato do payload: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" ou "EIP712_TYPED_DATA_V1". Para mais informações, consulte Nomes de esquemas.
blockchain String Sim "ETH", "BTC" ou "SOL".
principal_keyring String Sim O ID do KeyRing que contém a chave de assinatura, por exemplo, "treasury".
principal_key String Sim O ID da chave de assinatura, por exemplo, "hot-wallet-1".
secondary_key String Sim O endereço de destino, o destinatário do token ou NFT, o pagador ou operador aprovado ou a contraparte do EIP-712 decodificada do payload.
amount_token_scaled Long Não O valor fungível transferido ou aprovado, em unidades de 10-9 do ativo. Omitido quando nenhum valor fungível é transferido, por exemplo, uma operação ERC-721 ou uma chamada de contrato que não envia ETH. Para mais informações, consulte Valores.
token_symbol String Não O símbolo do ativo, por exemplo, "ETH", "BTC", "SOL" ou "USDC". Omitido quando o recurso não é reconhecido pela computação multipartidária e para operações ERC-721.
contract_address String Não O contrato de token ERC-20 ou ERC-721 ou o contrato chamado (Ethereum), o contrato de verificação (EIP-712) ou o mint (Solana). Omitido para transferências nativas.
token_standard String Não "ERC721" para transferências e aprovações de ERC-721 (ETHEREUM_TX_V2). Omitido para transferências nativas e operações de token fungível.
token_id String Não O tokenId ERC-721 de 256 bits como uma string de base 10 (ETHEREUM_TX_V2). Omitido para setApprovalForAll e para transações que não são ERC-721.
from_address String Não O proprietário atual (from) nas chamadas ERC-721 transferFrom e safeTransferFrom, no formato de checksum EIP-55 com letras maiúsculas e minúsculas.
approve_all Bool Não A flag approved em chamadas setApprovalForAll(operator, approved) do ERC-721: true ao conceder aprovação do operador, false ao revogá-la.
deadline Long Não O prazo de validade de uma mensagem EIP712_TYPED_DATA_V1, em segundos desde a época Unix, do campo deadline, sigDeadline ou validBefore.
eip712 Record Não O payload estruturado do EIP-712: primary_type, domain e message, com números inteiros de 256 bits como strings de base 10. Somente EIP712_TYPED_DATA_V1.
chain_id Long Não O ID da cadeia de EVM, por exemplo, 1 para a mainnet da Ethereum ou 11155111 para a Sepolia. Somente Ethereum e EIP-712.
max_fee_atomic Long Sim O valor máximo que a transação pode pagar em taxas de rede, em unidades de 10-9 da moeda nativa do blockchain. 0 por EIP712_TYPED_DATA_V1.
payload String Sim O resumo codificado em hexadecimal do payload, em letras minúsculas.
time_stamp Long Sim O createTime da transação, em segundos desde o início da época Unix.
key_lists Record de Set<String> Sim Um registro que mapeia cada ID de KeyList na instância para o Set<String> de endereços de blockchain nessa KeyList, resolvido em createTime. Um registro vazio quando a instância não tem KeyLists. Ler uma KeyList com sintaxe de colchetes, por exemplo, context.key_lists["trusted-destinations"]. Para mais informações, consulte KeyLists no contexto do Cedar.

principal_keyring e principal_key são IDs, não nomes de recursos completos. Um ID de chave é exclusivo apenas no KeyRing. Marque principal_keyring para aplicar uma regra a todas as chaves em um KeyRing ou ambos os atributos para nomear uma chave:

context.principal_keyring == "treasury" && context.principal_key == "hot-wallet-1"

Se o payload não puder ser decodificado pelo analisador para Transaction.schema ou não puder ser projetado em um contexto, nenhuma política será avaliada e a transação será negada com UNRECOGNIZED_PAYLOAD. Para mais informações, consulte Motivos de negação.

Nomes de esquemas

O atributo schema é o nome do valor PayloadSchema na API v1beta: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" ou "EIP712_TYPED_DATA_V1". Os nomes em letras minúsculas usados pelas regras v1alpha1, como "ethereum.transaction.v2", nunca correspondem em v1beta.

Uma regra sem uma verificação schema ou blockchain se aplica a todos os blockchains. Para limitar uma regra a um blockchain, marque schema.

Valores

amount_token_scaled e max_fee_atomic usam a mesma escala para todos os recursos: 1 unidade é 10-9 do recurso, então 1,0 de qualquer recurso é 1000000000. Para receber o valor de uma regra, multiplique o valor por 1.000.000.000 (109). A tabela a seguir mostra alguns exemplos:

Valor amount_token_scaled
0,1 ETH 100000000
1,0 ETH, 1,0 BTC, 1,0 SOL ou 1,0 USDC 1000000000
0,0025 BTC (250.000 satoshis) 2500000
1,5 SOL (1.500.000.000 lamports) 1500000000
5.000 USDC 5000000000000

Para ativos com mais de 9 casas decimais, como ETH, a parte do valor menor que 10-9 é descartada. Uma regra não pode verificar isso.

Ethereum

A tabela a seguir descreve os atributos de contexto para payloads ETHEREUM_TX_V2 (transações legadas codificadas por RLP e EIP-2718, incluindo EIP-1559):

Atributo Valor
secondary_key Para transferências de ETH e chamadas de contrato, o endereço to da transação. Para ERC-20 transfer e transferFrom, e ERC-721 transferFrom e safeTransferFrom, o destinatário do token ou NFT. Para ERC-20 e ERC-721 approve, o gastador aprovado. Para ERC-721 setApprovalForAll, o operador. No formato de checksum EIP-55 com letras maiúsculas e minúsculas.
amount_token_scaled Para transferências de ETH e transferências e aprovações de ERC-20, o valor. Para chamadas de contrato, o ETH enviado com a chamada. Omitido se nenhum ETH for enviado. Sempre omitido para transferências e aprovações de ERC-721, para que os limites de gastos fungíveis não correspondam aos IDs de token de NFT.
token_symbol "ETH" para transferências de ETH e para chamadas de contrato que enviam ETH. Para tokens ERC-20 reconhecidos na rede principal do Ethereum, "USDC", "USDT", "DAI" ou "WBTC". Omitido para outros tokens e para operações ERC-721.
contract_address Para transferências e aprovações de ERC-20 e ERC-721, o contrato de token ou NFT. Para chamadas de contrato, o contrato chamado. No formato de checksum EIP-55 com letras maiúsculas e minúsculas. Omitido para transferências de ETH.
token_standard "ERC721" para transferências e aprovações de ERC-721. Omitido para transferências de ETH, operações ERC-20 e outras chamadas de contrato.
token_id Para ERC-721 transferFrom, safeTransferFrom e approve, o tokenId de 256 bits como uma String de base 10, para que os IDs de NFT nunca estourem o Long de 64 bits do Cedar. Como é um String, compare-o para confirmar se é igual a == ou in [...]. < e > comparam strings, não números. Omitido para setApprovalForAll e para transações que não são ERC-721.
from_address Para ERC-721 transferFrom e safeTransferFrom, o proprietário atual (from), no formato de checksum EIP-55 com letras maiúsculas e minúsculas.
approve_all Para ERC-721 setApprovalForAll(operator, approved), a flag approved como Bool: true ao conceder a aprovação do operador em cada NFT na coleção, false ao revogá-la.
chain_id O ID da rede da transação. Pode ser omitido em transações legadas. Portanto, verifique com has.
max_fee_atomic Limite de gás × taxa máxima por gás (ou preço do gás para transações legadas), em gwei.

Para o ERC-20 transfer(address, uint256) (0xa9059cbb), cujo seletor é exclusivo do ERC-20, um token que a computação multipartidária não reconhece tem o valor dimensionado como se o token tivesse 18 casas decimais. Faça a correspondência de tokens reconhecidos por contract_address e não defina limites de valor em tokens não reconhecidos com decimais diferentes de 18. O ERC-20 transferFrom e o approve compartilham os seletores com o ERC-721, então eles precisam de um contrato reconhecido. Uma chamada para um contrato não reconhecido com um desses seletores é negada com UNRECOGNIZED_PAYLOAD. Para mais informações, consulte tokens não fungíveis ERC-721.

O contexto não diz que tipo de transação do Ethereum é, então lembre-se do seguinte:

  • As chamadas de contrato que enviam ETH parecem transferências de ETH. Ambos têm token_symbol "ETH" e um amount_token_scaled. Somente uma chamada de contrato tem contract_address. Para permitir apenas transferências de ETH, adicione !(context has contract_address).
  • As aprovações de ERC-20 se parecem com as transferências de ERC-20. Um approve tem os mesmos contract_address, amount_token_scaled e secondary_key (o pagador) que uma transferência do mesmo valor para o mesmo endereço. Uma política que permite a transferência também permite a aprovação.

As transações de criação de contrato (com um endereço to vazio) não podem ser decodificadas e são negadas com UNRECOGNIZED_PAYLOAD.

Tokens não fungíveis ERC-721

Em ETHEREUM_TX_V2, a computação multipartidária decodifica os seguintes métodos ERC-721:

  • safeTransferFrom(address from, address to, uint256 tokenId) (0x42842e0e)
  • safeTransferFrom(address from, address to, uint256 tokenId, bytes data) (0xb88d4fde)
  • transferFrom(address from, address to, uint256 tokenId) (0x23b872dd)
  • approve(address to, uint256 tokenId) (0x095ea7b3)
  • setApprovalForAll(address operator, bool approved) (0xa22cb465)

O ERC-20 e o ERC-721 compartilham os mesmos seletores de 4 bytes para transferFrom (0x23b872dd) e approve (0x095ea7b3). Para decidir se o argumento uint256 é um valor fungível ou um ID de token, a computação multipartidária procura o endereço do contrato to no registro de contratos de token reconhecidos. Para chamadas ERC-721, amount_token_scaled é omitido, token_standard é "ERC721" e token_id é um String de base 10. Uma chamada para um contrato não reconhecido com um desses seletores compartilhados é negada com UNRECOGNIZED_PAYLOAD.

Dados digitados do EIP-712

Para payloads EIP712_TYPED_DATA_V1 (dados digitados EIP-712 codificados em JSON UTF-8 com types, primaryType, domain e message), a computação multipartidária valida a estrutura JSON e calcula o resumo de assinatura EIP-712 de 32 bytes, keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)), em que ++ é a concatenação de bytes. A validação rejeita aninhamentos com mais de 15 níveis, tipos cíclicos, elementos de matriz null e campos domain que não correspondem a types.EIP712Domain, além de preservar números inteiros de 256 bits sem perda de precisão de usar pontos flutuantes.

Um payload EIP712_TYPED_DATA_V1 projeta os seguintes atributos:

Atributo Valor
blockchain Sempre "ETH".
schema Sempre "EIP712_TYPED_DATA_V1".
contract_address domain.verifyingContract, no formato de checksum EIP-55 com letras maiúsculas e minúsculas. Omitido quando o domínio não define verifyingContract.
chain_id domain.chainId como Long. Omitido quando o domínio não define chainId.
max_fee_atomic Sempre 0, porque a assinatura de dados tipados não paga uma taxa de rede.
secondary_key Para tipos de mensagem reconhecidos, a contraparte: spender para ERC-2612 Permit e Uniswap Permit2, ou to para ERC-3009 TransferWithAuthorization e Safe SafeTx. Para outros tipos de mensagem, domain.verifyingContract.
amount_token_scaled Para tipos de mensagem reconhecidos (Permit, Permit2, TransferWithAuthorization e SafeTx), o token autorizado ou o valor de ETH (value ou details.amount), em unidades de 10-9. Omitido para outros tipos de mensagem.
token_symbol "USDC", "USDT", "DAI" ou "WBTC" quando o contrato de verificação ou o token Permit2 (details.token) é um token reconhecido na rede principal do Ethereum. Caso contrário, será omitido.
deadline O prazo de validade da mensagem, em segundos desde a época Unix, quando a mensagem tem um campo deadline, sigDeadline ou validBefore. Caso contrário, será omitido.
eip712 Um Record com os dados digitados. Para mais informações, veja a tabela a seguir:

O registro eip712 tem os seguintes campos:

Campo Tipo Cedar Valor
context.eip712.primary_type String O nome do primaryType, por exemplo, "Permit", "PermitSingle", "TransferWithAuthorization" ou "SafeTx".
context.eip712.domain Record Os campos EIP712Domain que o payload define: name, version, chainId, verifyingContract e salt.
context.eip712.message Record Os campos message. Os valores inteiros de 256 bits (uint256 e int256) são Strings de base 10, portanto, as regras podem corresponder a valores exatos sem estouro de 64 bits.

Bitcoin

A tabela a seguir descreve os atributos de contexto para payloads BITCOIN_TX_V2 (BIP 174 PSBT v0):

Atributo Valor
secondary_key O endereço da saída que não é de troco. Para uma consolidação, em que cada saída é um troco, o endereço da primeira saída.
amount_token_scaled O valor enviado para secondary_key, sem contar o troco (1 satoshi = 10). 0 para uma consolidação.
token_symbol Sempre "BTC".
contract_address Nunca presente.
chain_id Nunca está presente, porque uma PSBT não diz a qual rede ela se destina. Os endereços são sempre formatados como endereços da Mainnet, então um endereço da Testnet também começa com bc1, 1 ou 3. O prefixo do endereço mostra o tipo de endereço, não a rede.
max_fee_atomic A taxa do minerador: total de entradas menos total de saídas (1 satoshi = 10).

Para manter as redes Bitcoin separadas, use chaves diferentes para cada rede, por exemplo, em um KeyRing para Mainnet e outro para Testnet, e defina regras de escopo para elas com principal_keyring ou principal_key. A mesma chave pode assinar as duas redes, então isso só funciona se você nunca usar uma chave da Mainnet na Testnet.

Uma transação que envia para mais de um endereço que não é de troco não pode ser decodificada. Uma transação sem endereço de envio, como uma em que a única saída que não é de troco é uma saída OP_RETURN, não pode ser avaliada.

Solana

A tabela a seguir descreve os atributos de contexto para payloads SOLANA_TX_V1 (mensagens Solana legadas não assinadas ou v0):

Atributo Valor
secondary_key Para transferências de SOL, a carteira de destino. Para transferências de tokens, a conta de token de destino, não a carteira que a possui. Em base58.
amount_token_scaled O valor. Para SOL, o número de lamports (1 lamport = 1). Para tokens, o valor bruto dimensionado com os decimais que a instrução TransferChecked carrega.
token_symbol "SOL" para transferências de SOL. Para tokens, "USDC", "USDT" ou "PYUSD". Omitido para outras emissões.
contract_address Para transferências de token, o endereço de mint, em base58. Omitido para transferências SOL.
chain_id Nunca presente. As mensagens da Solana não nomeiam um cluster.
max_fee_atomic O valor máximo que a transação inteira pode pagar em lamports: 5.000 para cada assinatura necessária, mais a taxa de prioridade, ⌈limite de unidades de computação × preço da unidade de computação em microlamports ÷ 106⌉, se a transação definir um preço para a unidade de computação.

Uma transação da Solana pode conter várias instruções:

  • Instruções de transferência:programa do sistema Transfer (SOL) e token SPL ou Token-2022 TransferChecked. A instrução Transfer não verificada e os tokens com mais de 9 casas decimais não podem ser decodificados.
  • Outras instruções:ComputeBudget SetComputeUnitLimit e SetComputeUnitPrice, Memo (v1 e v2), Associated Token Account Create e CreateIdempotent, e System Program AdvanceNonceAccount. Essas instruções não produzem um contexto próprio.

Cada instrução de transferência é avaliada separadamente com o próprio contexto. A transação só será permitida se todas as transferências forem permitidas. Se alguma transferência for negada, toda a transação será negada. max_fee_atomic é a taxa para toda a transação e é a mesma em todos os contextos. Portanto, não a adicione em todas as transferências.

Se a transação definir um preço de unidade de computação sem um limite de unidades de computação, a taxa vai usar o limite padrão da Solana de 200.000 unidades de computação para cada instrução que não seja do ComputeBudget, até 1.400.000.

Os signatários da transação precisam corresponder às contas que cada instrução precisa assinar, e as contas de origem e a conta de destino precisam ser graváveis. As mensagens v0 que usam tabelas de consulta de endereço não podem ser decodificadas. Transmita os bytes de mensagem não assinados, não um envelope de transação assinado, em Transaction.payload e Transaction.rawMessage.

As cunhagens reconhecidas são as da Solana Mainnet. Na Devnet ou na Testnet, uma transferência de token não tem token_symbol. Portanto, verifique contract_address.

Uma instrução de conta de token associada Create financia a reserva isenta de aluguel da nova conta em SOL. Esse valor não está em amount_token_scaled.

Exemplo de regras

Os exemplos a seguir são políticas permit e forbid que você pode adaptar. Cada exemplo verifica todos os atributos opcionais com has antes de ler.

Limite de compra para um KeyRing usando payload e metadados

Permitir transferências de buy_transaction de até 500.000 USDC na rede principal do Ethereum de qualquer chave no KeyRing institutional-treasury, quando o iniciador rotular a transação com "equities-desk", definir uma validade de no máximo 300 segundos e declarar um valor de no máximo US $500.000:

permit (
  principal,
  action == Action::"buy_transaction",
  resource == Resource::"transaction_management"
)
when {
  context.principal_keyring == "institutional-treasury" &&
  context.schema == "ETHEREUM_TX_V2" &&
  context has chain_id && context.chain_id == 1 &&
  context has contract_address &&
  context.contract_address == "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" &&
  context has amount_token_scaled && context.amount_token_scaled <= 500000000000000 &&
  context has fiat_amount && context.fiat_amount <= 500000 &&
  context has validity && context.validity <= 300 &&
  context has principal_value1 && context.principal_value1 == "equities-desk"
};

A computação multipartidária não compara fiat_amount com o payload. Para mais informações, consulte Atributos de contexto.

Limite de gastos para uma chave

Permitir transferências de até 1 ETH de uma chave na Mainnet da Ethereum. !(context has contract_address) exclui chamadas de contrato que enviam ETH:

permit (principal, action, resource)
when {
  context.principal_keyring == "treasury" &&
  context.principal_key == "hot-wallet-1" &&
  context.schema == "ETHEREUM_TX_V2" &&
  context has chain_id && context.chain_id == 1 &&
  context has token_symbol && context.token_symbol == "ETH" &&
  !(context has contract_address) &&
  context has amount_token_scaled && context.amount_token_scaled <= 1000000000
};

Lista de permissões de stablecoins no Ethereum

Permitir transferências de até 5.000 USDC para um endereço e aprovações (permissões) de até 5.000 USDC para esse endereço. A política verifica contract_address em vez de token_symbol. Portanto, um token de outro contrato que usa o mesmo símbolo não corresponde:

permit (principal, action, resource)
when {
  context.schema == "ETHEREUM_TX_V2" &&
  context has contract_address &&
  context.contract_address == "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" &&
  context.secondary_key == "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" &&
  context has amount_token_scaled && context.amount_token_scaled <= 5000000000000
};

token_symbol é "USDC" para esta transação.

Transferência ERC-721 e proteção de aprovação do operador

Permitir a transferência de uma nota do tesouro tokenizada (token_id == "1042") de um contrato ERC-721 aprovado para um endereço de liquidação e proibir a concessão de aprovações de operador em toda a coleção (setApprovalForAll com approve_all == true).

A política A permite uma transferência de NFT:

permit (
  principal,
  action == Action::"internal_transfer_transaction",
  resource == Resource::"transaction_management"
)
when {
  context.schema == "ETHEREUM_TX_V2" &&
  context has chain_id && context.chain_id == 1 &&
  context has token_standard && context.token_standard == "ERC721" &&
  context has contract_address &&
  context.contract_address == "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" &&
  context has token_id && context.token_id == "1042" &&
  context.secondary_key == "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"
};

A política B proíbe aprovações de operadores em toda a coleção:

forbid (principal, action, resource)
when {
  context.schema == "ETHEREUM_TX_V2" &&
  context has approve_all && context.approve_all == true
};

Limite de permissão de USDC sem gás do EIP-712

Permitir a assinatura de um Permit ERC-2612 fora da rede para até 25.000 USDC na rede principal do Ethereum para um roteador de liquidação aprovado, quando a permissão expirar antes de um determinado horário:

permit (
  principal,
  action == Action::"buy_transaction",
  resource == Resource::"transaction_management"
)
when {
  context.schema == "EIP712_TYPED_DATA_V1" &&
  context has chain_id && context.chain_id == 1 &&
  context has contract_address &&
  context.contract_address == "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" &&
  context has eip712 && context.eip712.primary_type == "Permit" &&
  context.secondary_key == "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" &&
  context has amount_token_scaled && context.amount_token_scaled <= 25000000000000 &&
  context has deadline && context.deadline <= 1793491200
};

Limite de gastos e de taxas de Bitcoin

Permita transferências de até 0,0025 BTC com uma taxa de minerador de até 10.000 satoshis, de chaves em um KeyRing que você usa apenas na rede principal do Bitcoin:

permit (principal, action, resource)
when {
  context.schema == "BITCOIN_TX_V2" &&
  context.principal_keyring == "btc-mainnet" &&
  context has amount_token_scaled && context.amount_token_scaled <= 2500000 &&
  context.max_fee_atomic <= 100000
};

Transferência de SOL e limite de taxa de prioridade

Permitir transferências de até 1,5 SOL quando a taxa total, incluindo qualquer taxa de prioridade, for de no máximo 50.000 lamports (0,00005 SOL):

permit (principal, action, resource)
when {
  context.schema == "SOLANA_TX_V1" &&
  context has token_symbol && context.token_symbol == "SOL" &&
  !(context has contract_address) &&
  context has amount_token_scaled && context.amount_token_scaled <= 1500000000 &&
  context.max_fee_atomic <= 50000
};

Transferência de token SPL ou Token-2022 na Solana

Permitir transferências de até 250 USDC para uma conta de token. A mesma regra corresponde aos programas SPL Token e Token-2022, porque o contexto não diz qual programa a transferência usa:

permit (principal, action, resource)
when {
  context.schema == "SOLANA_TX_V1" &&
  context has contract_address &&
  context.contract_address == "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" &&
  context.secondary_key == "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin" &&
  context has amount_token_scaled && context.amount_token_scaled <= 250000000000
};

secondary_key é a conta de token do destinatário para essa cunhagem. Para permitir uma carteira de destinatário, liste a conta de token dela para cada mint que você permitir. Em uma transação com várias transferências, essa regra precisa corresponder a todas as transferências.

Bloco de recursos não reconhecido

Negar qualquer transferência em que o recurso de computação multipartidária não seja reconhecido. Esta política forbid usa apenas has, então não pode falhar na avaliação:

forbid (principal, action, resource)
when { context has amount_token_scaled }
unless { context has token_symbol };

Limite de taxa para um blockchain

max_fee_atomic está sempre presente, então essa política forbid não pode falhar na avaliação. Como a escala é de 10-9 de cada moeda nativa, o mesmo número é um valor diferente em cada blockchain. Defina o escopo da política para um blockchain:

forbid (principal, action, resource)
when { context.blockchain == "ETH" && context.max_fee_atomic > 10000000 };

Isso nega transações do Ethereum que podem pagar mais de 0,01 ETH em taxas.

KeyRings

Um KeyRing é um contêiner estático que agrupa chaves de MPC, por exemplo, "institutional-treasury" ou "btc-cold-storage". Cada chave é criada dentro de um único KeyRing e permanece nele permanentemente.

Os KeyRings participam das políticas de três maneiras:

  • KeyRing KeyPolicy (quórum de assinatura). Ao criar um KeyRing, você define o KeyPolicy imutável, que define a árvore de limite de equipes e usuários que têm compartilhamentos de chaves e precisam aprovar antes que qualquer chave no KeyRing possa assinar. As políticas de transação funcionam com o KeyPolicy: a política de transação avalia as regras de negócios para o payload (PERMIT ou DENY), enquanto o KeyPolicy do KeyRing determina quais compartilhamentos de chaves precisam autorizar a cerimônia de assinatura.
  • Escopo de políticas de transação por KeyRing de assinatura (context.principal_keyring). O contexto de cada transação inclui context.principal_keyring, definido como o ID do KeyRing que contém a chave de assinatura, e context.principal_key, definido como o ID da chave de assinatura. Uma regra com context.principal_keyring == "institutional-treasury" se aplica a todas as chaves no KeyRing, incluindo as criadas posteriormente, sem criar ou aprovar uma nova política:

    permit (
      principal,
      action == Action::"internal_transfer_transaction",
      resource == Resource::"transaction_management"
    )
    when {
      context.principal_keyring == "institutional-treasury" &&
      context has fiat_amount && context.fiat_amount <= 100000
    };
    
  • Lista de permissões do KeyRing de destino (em uma KeyList). Também é possível adicionar um KeyRing como uma entrada em uma KeyList para que as transferências para o endereço de blockchain de qualquer chave ativa nesse KeyRing, como varreduras internas entre KeyRings quentes e frios, sejam permitidas automaticamente à medida que novas chaves são criadas. Para ver um exemplo, consulte Lista de permissões e de bloqueio de KeyList.

Lista de permissões e lista de bloqueio do KeyList

Permitir transferências de até 1 ETH apenas para endereços na KeyList trusted-destinations. context.key_lists["trusted-destinations"] é o conjunto de endereços para o qual a KeyList se expande no createTime da transação. Portanto, adicionar ou remover uma entrada muda o que essa regra permite sem uma nova política:

// Assuming you created a KeyList with ID "trusted-destinations":
permit (principal, action, resource)
when {
  context.schema == "ETHEREUM_TX_V2" &&
  context has token_symbol && context.token_symbol == "ETH" &&
  !(context has contract_address) &&
  context.key_lists["trusted-destinations"].contains(context.secondary_key) &&
  context has amount_token_scaled && context.amount_token_scaled <= 1000000000
};

Negar qualquer transação para um endereço na KeyList blocked-addresses, em todos os blockchains. key_lists e secondary_key estão sempre presentes, e CreateTransactionPolicy verifica se a KeyList existe. Portanto, essa política forbid não pode falhar na avaliação:

// Assuming you created a KeyList with ID "blocked-addresses":
forbid (principal, action, resource)
when { context.key_lists["blocked-addresses"].contains(context.secondary_key) };

Escreva o ID da KeyList na sintaxe de colchetes, context.key_lists["..."], em vez da sintaxe de ponto. A sintaxe de ponto não consegue analisar IDs que contêm um hífen ou começam com um dígito. As entradas são comparadas como strings. Portanto, adicione entradas manuais no formato de endereço descrito na tabela de cada blockchain. Para mais informações, consulte KeyLists no contexto do Cedar.