Cette page décrit les attributs qu'une règle de transaction peut vérifier et présente des exemples de règles pour les transactions Ethereum (ETHEREUM_TX_V2 et EIP712_TYPED_DATA_V1), Bitcoin (BITCOIN_TX_V2) et Solana (SOLANA_TX_V1).
Pour savoir comment les règles sont combinées, quelles règles sont appliquées et pourquoi une transaction est refusée, consultez Évaluation des règles de transaction.
Structure des règles
Une stratégie de transaction est une instruction Cedar
permit ou forbid unique sur le compte principal, l'action, la ressource et le contexte :
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
};
Tenez bien compte des éléments suivants :
- Les attributs se trouvent au niveau supérieur du contexte. Écrivez
context.amount_token_scaled, et noncontext.transaction.spend_amount_scaled, comme dansv1alpha1. - Certains attributs sont facultatifs. Un attribut facultatif qui ne se trouve pas dans le contexte entraîne l'échec de l'évaluation de la stratégie, et une stratégie dont l'évaluation échoue ne correspond pas. Vérifiez si un attribut facultatif est présent avec
hasavant de le lire, ou avecunless { context has ... }dans une règleforbid. Pour en savoir plus, consultez les sections Scénario 6 et Scénario 8. - Les chaînes Cedar sont sensibles à la casse. Comparez les adresses au format décrit dans le tableau de chaque chaîne.
Pour le principal, consultez La requête Cedar. Pour connaître les actions acceptées par CreateTransaction (buy_transaction, sell_transaction et internal_transfer_transaction), consultez Action et ressource.
Attributs de contexte
Le contexte de chaque transaction comporte les attributs décodés à partir de sa charge utile, les ID de la clé de signature et de son trousseau de clés, ainsi que les attributs de métadonnées (fiat_amount, validity, principal_value1 et principal_value2) définis par l'initiateur.
Les attributs de charge utile sont les mêmes pour chaque blockchain. Le tableau suivant décrit tous les attributs de contexte, et les tableaux pour Ethereum, Bitcoin et Solana décrivent comment le calcul multipartite remplit chaque attribut pour cette blockchain :
| Attribut | Type Cedar | Toujours présent ? | Valeur |
|---|---|---|---|
schema |
String |
Oui | Format de la charge utile : "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" ou "EIP712_TYPED_DATA_V1". Pour en savoir plus, consultez Noms de schémas. |
blockchain |
String |
Oui | "ETH", "BTC" ou "SOL". |
principal_keyring |
String |
Oui | ID du trousseau de clés contenant la clé de signature, par exemple "treasury". |
principal_key |
String |
Oui | ID de la clé de signature, par exemple "hot-wallet-1". |
secondary_key |
String |
Oui | L'adresse de destination, le destinataire du jeton ou du NFT, le dépensier ou l'opérateur approuvé, ou la contrepartie EIP-712 décodée à partir de la charge utile. |
amount_token_scaled |
Long |
Non | Montant fongible transféré ou approuvé, en unités de 10-9 de l'élément. Omis lorsqu'aucun montant fongible n'est transféré, par exemple une opération ERC-721 ou un appel de contrat qui n'envoie pas d'ETH. Pour en savoir plus, consultez Montants. |
token_symbol |
String |
Non | Symbole de l'actif, par exemple "ETH", "BTC", "SOL" ou "USDC". Omis lorsque l'asset n'est pas reconnu par le calcul multipartite et pour les opérations ERC-721. |
contract_address |
String |
Non | Contrat de jeton ERC-20 ou ERC-721, ou contrat appelé (Ethereum), contrat de vérification (EIP-712) ou mint (Solana). Omis pour les transferts natifs. |
token_standard |
String |
Non | "ERC721" pour les transferts et les approbations ERC-721 (ETHEREUM_TX_V2). Omis pour les transferts natifs et les opérations de jetons fongibles. |
token_id |
String |
Non | tokenId ERC-721 256 bits sous forme de chaîne en base 10 (ETHEREUM_TX_V2). Omis pour setApprovalForAll et pour les transactions qui ne sont pas ERC-721. |
from_address |
String |
Non | Le propriétaire actuel (from) dans les appels ERC-721 transferFrom et safeTransferFrom, au format de somme de contrôle EIP-55 mixte. |
approve_all |
Bool |
Non | L'indicateur approved dans les appels setApprovalForAll(operator, approved) ERC-721 : true lors de l'octroi de l'approbation de l'opérateur, false lors de sa révocation. |
deadline |
Long |
Non | Heure d'expiration d'un message EIP712_TYPED_DATA_V1, en secondes depuis l'epoch Unix, à partir de son champ deadline, sigDeadline ou validBefore. |
eip712 |
Record |
Non | La charge utile EIP-712 structurée : primary_type, domain et message, avec des entiers de 256 bits sous forme de chaînes en base 10. EIP712_TYPED_DATA_V1 uniquement. |
chain_id |
Long |
Non | ID de la chaîne EVM, par exemple 1 pour le réseau principal Ethereum ou 11155111 pour Sepolia. Ethereum et EIP-712 uniquement. |
max_fee_atomic |
Long |
Oui | Montant maximal que la transaction peut payer en frais de réseau, en unités de 10-9 de la pièce native de la blockchain. 0 pour EIP712_TYPED_DATA_V1. |
payload |
String |
Oui | Condensé de la charge utile encodé en hexadécimal, en minuscules. |
time_stamp |
Long |
Oui | createTime de la transaction, en secondes depuis l'epoch Unix. |
key_lists |
Record sur Set<String> |
Oui | Enregistrement mappant chaque ID KeyList de l'instance au Set<String> d'adresses de blockchain dans cette KeyList, résolu à createTime. Un enregistrement vide lorsque l'instance ne comporte pas de KeyLists. Lire une KeyList avec la syntaxe entre crochets, par exemple context.key_lists["trusted-destinations"]. Pour en savoir plus, consultez KeyLists dans le contexte Cedar. |
principal_keyring et principal_key sont des ID, et non des noms de ressources complets. Un ID de clé n'est unique que dans son trousseau de clés. Cochez principal_keyring pour appliquer une règle à chaque clé d'un trousseau de clés, ou les deux attributs pour nommer une clé :
context.principal_keyring == "treasury" && context.principal_key == "hot-wallet-1"
Si la charge utile ne peut pas être décodée par l'analyseur pour Transaction.schema ou ne peut pas être projetée dans un contexte, aucune règle n'est évaluée et la transaction est refusée avec UNRECOGNIZED_PAYLOAD. Pour en savoir plus, consultez Motifs de refus.
Noms de schéma
L'attribut schema est le nom de la valeur PayloadSchema dans l'API v1beta : "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" ou "EIP712_TYPED_DATA_V1". Les noms en minuscules utilisés par les règles v1alpha1, tels que "ethereum.transaction.v2", ne correspondent jamais dans v1beta.
Une règle sans vérification schema ou blockchain s'applique à toutes les blockchains.
Pour limiter une règle à une seule blockchain, cochez schema.
Montants
amount_token_scaled et max_fee_atomic utilisent la même échelle pour chaque élément : une unité correspond à 10-9 de l'élément.Par conséquent, 1,0 de n'importe quel élément correspond à 1000000000.
Pour obtenir la valeur d'une règle, multipliez le montant par 1 000 000 000 (109). Vous trouverez quelques exemples dans le tableau suivant :
| Montant | 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 |
Pour les éléments comportant plus de neuf décimales, tels que l'ETH, la partie du montant inférieure à 10-9 est supprimée. Une règle ne peut pas le vérifier.
Ethereum
Le tableau suivant décrit les attributs de contexte pour les charges utiles ETHEREUM_TX_V2 (anciennes transactions encodées en RLP et transactions EIP-2718, y compris EIP-1559) :
| Attribut | Valeur |
|---|---|
secondary_key |
Pour les transferts d'ETH et les appels de contrat, l'adresse to de la transaction. Pour les jetons ERC-20 transfer et transferFrom, et les NFT ERC-721 transferFrom et safeTransferFrom, le destinataire du jeton ou du NFT. Pour les approve ERC-20 et ERC-721, le dépensier approuvé. Pour ERC-721 setApprovalForAll, l'opérateur. Au format de somme de contrôle EIP-55 en casse mixte. |
amount_token_scaled |
Pour les transferts ETH, ainsi que les transferts et approbations ERC-20, le montant. Pour les appels de contrat, l'ETH envoyé avec l'appel ; omis si aucun ETH n'est envoyé. Toujours omis pour les transferts et les approbations ERC-721, afin que les limites de dépenses fongibles ne correspondent pas aux ID de jeton NFT. |
token_symbol |
"ETH" pour les transferts d'ETH et pour les appels de contrat qui envoient des ETH. Pour les jetons ERC-20 reconnus sur Ethereum Mainnet, "USDC", "USDT", "DAI" ou "WBTC" ; omis pour les autres jetons et pour les opérations ERC-721. |
contract_address |
Pour les transferts et les approbations ERC-20 et ERC-721, le contrat du jeton ou du NFT. Pour les appels de contrat, le contrat appelé. Au format de somme de contrôle EIP-55 en casse mixte. Omis pour les transferts d'ETH. |
token_standard |
"ERC721" pour les transferts et les approbations ERC-721. Omis pour les transferts ETH, les opérations ERC-20 et les autres appels de contrat. |
token_id |
Pour les ERC-721 transferFrom, safeTransferFrom et approve, l'tokenId 256 bits en tant que String en base 10, de sorte que les ID NFT ne dépassent jamais l'Long 64 bits de Cedar. Comme il s'agit d'un String, comparez-le pour vérifier s'il est égal à == ou in [...]. < et > comparent des chaînes, pas des nombres. Omis pour setApprovalForAll et pour les transactions qui ne sont pas ERC-721. |
from_address |
Pour les jetons ERC-721 transferFrom et safeTransferFrom, le propriétaire actuel (from), au format de somme de contrôle EIP-55 en casse mixte. |
approve_all |
Pour ERC-721 setApprovalForAll(operator, approved), l'option approved en tant que Bool : true lors de l'octroi de l'approbation de l'opérateur sur chaque NFT de la collection, false lors de sa révocation. |
chain_id |
ID de la chaîne de la transaction. Peut être omis sur les transactions anciennes. Vérifiez-le donc avec has. |
max_fee_atomic |
Limite de gaz × frais maximum par gaz (ou prix du gaz pour les transactions anciennes), en gwei. |
Pour les jetons ERC-20 transfer(address, uint256) (0xa9059cbb), dont le sélecteur est propre à ERC-20, un jeton que le calcul multipartite ne reconnaît pas voit son montant mis à l'échelle comme si le jeton comportait 18 décimales. Faites correspondre les jetons reconnus par contract_address et ne définissez pas de limites de montant pour les jetons non reconnus dont le nombre de décimales n'est pas de 18. transferFrom et approve ERC-20 partagent leurs sélecteurs avec ERC-721. Ils ont donc besoin d'un contrat reconnu. Un appel à un contrat non reconnu avec l'un de ces sélecteurs est refusé avec UNRECOGNIZED_PAYLOAD. Pour en savoir plus, consultez Jetons non fongibles ERC-721.
Le contexte n'indique pas de quel type de transaction Ethereum il s'agit. Gardez donc à l'esprit les points suivants :
- Les appels de contrat qui envoient des ETH ressemblent à des transferts d'ETH. Les deux ont un
token_symbol"ETH"et unamount_token_scaled. Seul un appel de contrat comportecontract_address. Pour n'autoriser que les transferts d'ETH, ajoutez!(context has contract_address). - Les approbations ERC-20 ressemblent à des transferts ERC-20. Un
approvea les mêmescontract_address,amount_token_scaledetsecondary_key(le payeur) qu'un transfert du même montant vers la même adresse. Une règle qui autorise le transfert autorise également l'approbation.
Les transactions de création de contrat (avec une adresse to vide) ne peuvent pas être décodées et sont refusées avec UNRECOGNIZED_PAYLOAD.
Jetons non fongibles ERC-721
Sous ETHEREUM_TX_V2, Multi-party Compute décode les méthodes ERC-721 suivantes :
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)
ERC-20 et ERC-721 partagent les mêmes sélecteurs de 4 octets pour transferFrom (0x23b872dd) et approve (0x095ea7b3). Pour déterminer si l'argument uint256 est un montant fongible ou un ID de jeton, le calcul multipartite recherche l'adresse du contrat to dans son registre des contrats de jetons reconnus. Pour les appels ERC-721, amount_token_scaled est omis, token_standard est "ERC721" et token_id est un String en base 10. Un appel à un contrat non reconnu avec l'un de ces sélecteurs partagés est refusé avec UNRECOGNIZED_PAYLOAD.
Données typées EIP-712
Pour les charges utiles EIP712_TYPED_DATA_V1 (données typées EIP-712 encodées en JSON UTF-8 avec types, primaryType, domain et message), le calcul multipartite valide la structure JSON et calcule le condensé de signature EIP-712 de 32 octets, keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)), où ++ est une concaténation d'octets. La validation rejette l'imbrication de plus de 15 niveaux, les types cycliques, les éléments de tableau null et les champs domain qui ne correspondent pas à types.EIP712Domain, et conserve les entiers de 256 bits sans perte de précision en virgule flottante.
Une charge utile EIP712_TYPED_DATA_V1 projette les attributs suivants :
| Attribut | Valeur |
|---|---|
blockchain |
Toujours "ETH". |
schema |
Toujours "EIP712_TYPED_DATA_V1". |
contract_address |
domain.verifyingContract, au format de somme de contrôle EIP-55 mixte. Omis lorsque le domaine ne définit pas verifyingContract. |
chain_id |
domain.chainId en tant que Long. Omis lorsque le domaine ne définit pas chainId. |
max_fee_atomic |
Toujours 0, car la signature de données typées n'entraîne pas de frais de réseau. |
secondary_key |
Pour les types de messages reconnus, la contrepartie : spender pour ERC-2612 Permit et Uniswap Permit2, ou to pour ERC-3009 TransferWithAuthorization et Safe SafeTx. Pour les autres types de messages, domain.verifyingContract. |
amount_token_scaled |
Pour les types de messages reconnus (Permit, Permit2, TransferWithAuthorization et SafeTx), le jeton autorisé ou la valeur ETH (value ou details.amount), en unités de 10-9. Omis pour les autres types de messages. |
token_symbol |
"USDC", "USDT", "DAI" ou "WBTC" lorsque le contrat de validation ou le jeton Permit2 (details.token) est un jeton reconnu sur le réseau principal Ethereum. Sinon, il est omis. |
deadline |
Heure d'expiration du message, en secondes depuis l'epoch Unix, lorsque le message comporte un champ deadline, sigDeadline ou validBefore. Sinon, il est omis. |
eip712 |
Record avec les données saisies. Pour en savoir plus, consultez le tableau ci-dessous. |
L'enregistrement eip712 comporte les champs suivants :
| Champ | Type Cedar | Valeur |
|---|---|---|
context.eip712.primary_type |
String |
Le nom de l'primaryType, par exemple "Permit", "PermitSingle", "TransferWithAuthorization" ou "SafeTx". |
context.eip712.domain |
Record |
Champs EIP712Domain définis par la charge utile : name, version, chainId, verifyingContract et salt. |
context.eip712.message |
Record |
Le champ message. Les valeurs entières de 256 bits (uint256 et int256) sont des Strings en base 10. Les règles peuvent donc correspondre à des valeurs exactes sans dépassement de capacité de 64 bits. |
Bitcoin
Le tableau suivant décrit les attributs de contexte pour les charges utiles BITCOIN_TX_V2 (BIP 174 PSBT v0) :
| Attribut | Valeur |
|---|---|
secondary_key |
Adresse de la sortie qui n'est pas une monnaie de rendu. Pour une consolidation, où chaque sortie est une monnaie de rendu, l'adresse de la première sortie. |
amount_token_scaled |
Montant envoyé à secondary_key, sans compter la monnaie (1 satoshi = 10). 0 pour une consolidation. |
token_symbol |
Toujours "BTC". |
contract_address |
Jamais présent. |
chain_id |
Jamais présent, car un PSBT n'indique pas à quel réseau il est destiné. Les adresses sont toujours formatées en tant qu'adresses Mainnet. Par conséquent, une adresse Testnet commence également par bc1, 1 ou 3. Le préfixe de l'adresse indique le type d'adresse, et non le réseau. |
max_fee_atomic |
Frais de minage : total des entrées moins total des sorties (1 satoshi = 10). |
Pour séparer les réseaux Bitcoin, utilisez des clés différentes pour chaque réseau, par exemple dans un trousseau de clés pour Mainnet et un autre pour Testnet, et appliquez-leur des règles de champ d'application avec principal_keyring ou principal_key. La même clé peut signer sur les deux réseaux. Cela ne fonctionne donc que si vous n'utilisez jamais de clé Mainnet sur Testnet.
Une transaction qui envoie vers plusieurs adresses qui ne sont pas des adresses de monnaie de rendu ne peut pas être décodée. Une transaction sans adresse d'envoi, par exemple une transaction dont la seule sortie qui n'est pas une monnaie est une sortie OP_RETURN, ne peut pas être évaluée.
Solana
Le tableau suivant décrit les attributs de contexte des charges utiles SOLANA_TX_V1 (messages Solana v0 ou anciens non signés) :
| Attribut | Valeur |
|---|---|
secondary_key |
Pour les transferts SOL, le portefeuille de destination. Pour les transferts de jetons, le compte de jeton de destination, et non le portefeuille qui le possède. En base58. |
amount_token_scaled |
Le montant. Pour SOL, le nombre de lamports (1 lamport = 1). Pour les jetons, le montant brut mis à l'échelle avec les décimales de l'instruction TransferChecked. |
token_symbol |
"SOL" pour les transferts de SOL. Pour les jetons, "USDC", "USDT" ou "PYUSD" ; omis pour les autres types de monnaie. |
contract_address |
Pour les transferts de jetons, l'adresse de mint, en base58. Omis pour les transferts SOL. |
chain_id |
Jamais présent. Les messages Solana ne nomment pas de cluster. |
max_fee_atomic |
Le montant maximal que l'ensemble de la transaction peut payer en lamports : 5 000 pour chaque signature requise, plus les frais de priorité, ⌈limite d'unités de calcul × prix de l'unité de calcul en micro-lamports ÷ 106⌉, si la transaction définit un prix d'unité de calcul. |
Une transaction Solana peut contenir plusieurs instructions :
- Instructions de transfert : programme système
Transfer(SOL), et jeton SPL ou Token-2022TransferChecked. L'instructionTransfernon cochée et les jetons comportant plus de neuf décimales ne peuvent pas être décodés. - Autres instructions : ComputeBudget
SetComputeUnitLimitetSetComputeUnitPrice, Memo (v1 et v2), Associated Token AccountCreateetCreateIdempotent, et System ProgramAdvanceNonceAccount. Ces instructions ne produisent pas de contexte qui leur est propre.
Chaque instruction de transfert est évaluée séparément avec son propre contexte. La transaction n'est autorisée que si chaque transfert est autorisé. Si un transfert est refusé, l'ensemble de la transaction est refusé. max_fee_atomic correspond aux frais pour l'ensemble de la transaction et est identique dans tous les contextes. Ne l'ajoutez donc pas aux transferts.
Si la transaction définit un prix d'unité de calcul sans limite d'unités de calcul, les frais utilisent la limite par défaut de Solana de 200 000 unités de calcul pour chaque instruction autre que les instructions ComputeBudget, jusqu'à 1 400 000.
Les signataires de la transaction doivent correspondre aux comptes que chaque instruction doit signer, et les comptes source et de destination doivent être accessibles en écriture. Les messages v0 qui utilisent des tables de conversion d'adresses ne peuvent pas être décodés. Transmettez les octets du message non signé, et non une enveloppe de transaction signée, dans Transaction.payload et Transaction.rawMessage.
Les mints reconnus sont les mints Solana Mainnet. Sur Devnet ou Testnet, un transfert de jeton n'a pas de token_symbol. Vérifiez donc plutôt contract_address.
Une instruction de compte de jeton associé Create finance la réserve de loyer du nouveau compte en SOL. Ce montant n'est pas en amount_token_scaled.
Exemples de règles
Les exemples suivants sont des règles permit et forbid que vous pouvez adapter.
Chaque exemple vérifie chaque attribut facultatif avec has avant de le lire.
Limite d'achat pour un trousseau de clés à l'aide de la charge utile et des métadonnées
Autorisez les transferts buy_transaction d'un montant maximal de 500 000 USDC sur Ethereum Mainnet à partir de n'importe quelle clé du trousseau de clés institutional-treasury, lorsque l'initiateur étiquette la transaction avec "equities-desk", définit une validité d'au plus 300 secondes et indique une valeur d'au plus 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"
};
Le calcul multipartite ne vérifie pas fiat_amount par rapport à la charge utile. Pour en savoir plus, consultez Attributs de contexte.
Limite de dépense pour une clé
Autoriser les transferts d'ETH jusqu'à 1 ETH à partir d'une clé sur le réseau principal Ethereum.
!(context has contract_address) exclut les appels de contrat qui envoient des 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
};
Liste d'autorisation de stablecoins sur Ethereum
Autoriser les transferts de 5 000 USDC maximum vers une adresse, et les approbations (allocations) de 5 000 USDC maximum pour cette adresse. La règle vérifie contract_address plutôt que token_symbol. Par conséquent, un jeton d'un autre contrat qui utilise le même symbole ne correspond pas :
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 est "USDC" pour cette transaction.
Protection du transfert et de l'approbation de l'opérateur ERC-721
Autoriser le transfert d'un bon du Trésor tokenisé (token_id == "1042") d'un contrat ERC-721 approuvé vers une adresse de règlement, et interdire l'octroi d'approbations d'opérateur à l'échelle de la collection (setApprovalForAll avec approve_all == true).
La stratégie A autorise le transfert d'un 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"
};
La règle B interdit les approbations d'opérateurs à l'échelle de la collection :
forbid (principal, action, resource)
when {
context.schema == "ETHEREUM_TX_V2" &&
context has approve_all && context.approve_all == true
};
Limite d'autorisation USDC sans frais de gaz EIP-712
Autoriser la signature d'un Permit ERC-2612 hors chaîne pour un montant maximal de 25 000 USDC sur le réseau principal Ethereum pour un routeur de règlement approuvé, lorsque l'autorisation expire avant une heure donnée :
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 dépense et plafond des frais pour le Bitcoin
Autorisez les transferts d'un montant maximal de 0,0025 BTC avec des frais de mineur d'un montant maximal de 10 000 satoshis, à partir de clés d'un trousseau de clés que vous n'utilisez que sur Bitcoin Mainnet :
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
};
Limite de transfert de SOL et de frais de priorité
Autorisez les transferts SOL d'un montant maximal de 1,5 SOL lorsque les frais totaux, y compris les frais de priorité, sont d'au plus 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
};
Transfert de jeton SPL ou Token-2022 sur Solana
Autoriser les transferts de 250 USDC maximum vers un compte de jeton. La même règle correspond aux programmes SPL Token et Token-2022, car le contexte n'indique pas quel programme le transfert utilise :
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 est le compte de jetons du destinataire pour cette frappe. Pour autoriser un portefeuille de destinataire, listez son compte de jeton pour chaque mint que vous autorisez. Dans une transaction comportant plusieurs transferts, cette règle doit correspondre à chaque transfert.
Bloc d'assets non reconnu
Refuser tout transfert dont l'asset n'est pas reconnu par le calcul multipartite. Cette règle forbid n'utilise que has. Son évaluation ne peut donc pas échouer :
forbid (principal, action, resource)
when { context has amount_token_scaled }
unless { context has token_symbol };
Plafond des frais pour une blockchain
max_fee_atomic est toujours présent, donc cette règle forbid ne peut pas échouer à l'évaluation. Étant donné que l'échelle est de 10-9 de chaque pièce native, le même nombre correspond à une valeur différente sur chaque blockchain. Limitez le champ d'application de la règle à une seule blockchain :
forbid (principal, action, resource)
when { context.blockchain == "ETH" && context.max_fee_atomic > 10000000 };
Cela refuse les transactions Ethereum qui peuvent payer plus de 0,01 ETH de frais.
Trousseaux
Un KeyRing est un conteneur statique qui regroupe des clés MPC, par exemple "institutional-treasury" ou "btc-cold-storage". Chaque clé est créée dans un seul trousseau de clés et y reste de manière permanente.
Les trousseaux de clés participent aux stratégies de trois manières :
- KeyRing
KeyPolicy(quorum de signature). Lorsque vous créez un trousseau de clés, vous définissez sa règle KeyPolicy immuable, qui définit l'arborescence de seuil des équipes et des utilisateurs qui détiennent des parts de clé et qui doivent approuver avant que toute clé du trousseau de clés puisse signer. Les règles de transaction fonctionnent conjointement avec laKeyPolicy: la règle de transaction évalue les règles métier de la charge utile (PERMITouDENY), tandis que laKeyPolicydu trousseau de clés détermine quelles parts de clé doivent autoriser la cérémonie de signature. Définir le champ d'application des règles de transaction par trousseau de clés de signature (
context.principal_keyring). Le contexte de chaque transaction inclutcontext.principal_keyring, défini sur l'ID du trousseau de clés contenant la clé de signature, etcontext.principal_key, défini sur l'ID de la clé de signature. Une règle aveccontext.principal_keyring == "institutional-treasury"s'applique à toutes les clés du trousseau de clés, y compris celles créées ultérieurement dans ce trousseau, sans qu'il soit nécessaire de créer ou d'approuver une nouvelle règle :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 };Liste d'autorisation de trousseaux de clés de destination (dans une KeyList). Vous pouvez également ajouter un KeyRing en tant qu'entrée dans une KeyList, de sorte que les transferts vers l'adresse de blockchain de n'importe quelle clé active de ce KeyRing, tels que les balayages internes entre les KeyRings chauds et froids, soient autorisés automatiquement à mesure que de nouvelles clés sont créées. Pour obtenir un exemple, consultez Liste d'autorisation et liste de blocage KeyList.
Liste d'autorisation et liste de blocage KeyList
Autoriser les transferts d'un maximum de 1 ETH uniquement vers les adresses de la liste de clés trusted-destinations. context.key_lists["trusted-destinations"] est l'ensemble d'adresses auquel la KeyList s'étend au niveau de la createTime de la transaction. Par conséquent, l'ajout ou la suppression d'une entrée modifie ce que cette règle autorise sans nouvelle stratégie :
// 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
};
Refuser toute transaction vers une adresse de la KeyList blocked-addresses, sur chaque blockchain. key_lists et secondary_key sont toujours présents, et CreateTransactionPolicy vérifie que la KeyList existe. Par conséquent, l'évaluation de cette règle forbid ne peut pas échouer :
// Assuming you created a KeyList with ID "blocked-addresses":
forbid (principal, action, resource)
when { context.key_lists["blocked-addresses"].contains(context.secondary_key) };
Écrivez l'ID KeyList dans la syntaxe entre crochets, context.key_lists["..."], plutôt que dans la syntaxe avec point. La syntaxe par point ne parvient pas à analyser les ID contenant un trait d'union ou commençant par un chiffre. Les entrées sont comparées en tant que chaînes. Ajoutez donc des entrées manuelles au format d'adresse décrit dans la table de chaque blockchain. Pour en savoir plus, consultez KeyLists dans le contexte Cedar.