Questa pagina descrive gli attributi che una policy di transazione può controllare e mostra regole di esempio per le transazioni Ethereum (ETHEREUM_TX_V2 e EIP712_TYPED_DATA_V1), Bitcoin (BITCOIN_TX_V2) e Solana (SOLANA_TX_V1).
Per scoprire come vengono combinate le policy, quali vengono applicate e perché una transazione viene rifiutata, consulta Valutazione delle policy delle transazioni.
Struttura delle regole
Una policy di transazione è una singola istruzione permit o forbid Cedar sull'entità, sull'azione, sulla risorsa e sul contesto:
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
};
Tieni presente che:
- Gli attributi si trovano al livello più alto del contesto. Scrivi
context.amount_token_scaled, noncontext.transaction.spend_amount_scaledcome inv1alpha1. - Alcuni attributi sono facoltativi. Un attributo facoltativo che non è presente nel contesto impedisce la valutazione della policy e una policy che non viene valutata non corrisponde. Verifica la presenza di un attributo facoltativo con
hasprima di leggerlo o conunless { context has ... }in una regolaforbid. Per saperne di più, consulta Scenario 6 e Scenario 8. - Le stringhe Cedar sono sensibili alle maiuscole. Confronta gli indirizzi nel formato descritto nella tabella per ogni catena.
Per l'entità, consulta
La richiesta Cedar. Per le azioni accettate da CreateTransaction (buy_transaction, sell_transaction e internal_transfer_transaction), consulta Azione e risorsa.
Attributi di contesto
Il contesto di ogni transazione ha gli attributi decodificati dal payload, gli ID della chiave di firma e del relativo keyring e gli attributi dei metadati (fiat_amount, validity, principal_value1 e principal_value2) impostati dall'iniziatore.
Gli attributi del payload sono gli stessi per ogni blockchain. La tabella seguente descrive tutti gli attributi di contesto, mentre le tabelle per Ethereum, Bitcoin e Solana descrivono in che modo il calcolo multipartitico compila ogni attributo per la blockchain:
| Attributo | Tipo di cedro | Sempre presente? | Valore |
|---|---|---|---|
schema |
String |
Sì | Il formato del payload: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" o "EIP712_TYPED_DATA_V1". Per saperne di più, consulta Nomi degli schemi. |
blockchain |
String |
Sì | "ETH", "BTC" o "SOL". |
principal_keyring |
String |
Sì | L'ID del keyring che contiene la chiave di firma, ad esempio "treasury". |
principal_key |
String |
Sì | L'ID della chiave di firma, ad esempio "hot-wallet-1". |
secondary_key |
String |
Sì | L'indirizzo di destinazione, il destinatario del token o dell'NFT, l'utente o l'operatore approvato o la controparte EIP-712 decodificata dal payload. |
amount_token_scaled |
Long |
No | L'importo fungibile trasferito o approvato, in unità di 10-9 dell'asset. Viene omesso quando non viene trasferito alcun importo fungibile, ad esempio un'operazione ERC-721 o una chiamata di contratto che non invia ETH. Per saperne di più, consulta Importi. |
token_symbol |
String |
No | Il simbolo dell'asset, ad esempio "ETH", "BTC", "SOL" o "USDC". Omesso quando l'asset non è riconosciuto dal calcolo multipartitico e per le operazioni ERC-721. |
contract_address |
String |
No | Il contratto del token ERC-20 o ERC-721 o il contratto chiamato (Ethereum), il contratto di verifica (EIP-712) o il mint (Solana). Omesso per i trasferimenti nativi. |
token_standard |
String |
No | "ERC721" per i trasferimenti e le approvazioni ERC-721 (ETHEREUM_TX_V2). Omesso per i trasferimenti nativi e le operazioni con token fungibili. |
token_id |
String |
No | tokenId ERC-721 a 256 bit come stringa in base 10 (ETHEREUM_TX_V2). Omesso per setApprovalForAll e per le transazioni che non sono ERC-721. |
from_address |
String |
No | Il proprietario attuale (from) nelle chiamate ERC-721 transferFrom e safeTransferFrom, nel formato di checksum EIP-55 con lettere maiuscole e minuscole. |
approve_all |
Bool |
No | Il flag approved nelle chiamate ERC-721 setApprovalForAll(operator, approved): true quando viene concessa l'approvazione dell'operatore, false quando viene revocata. |
deadline |
Long |
No | La scadenza di un messaggio EIP712_TYPED_DATA_V1, in secondi dall'epoca di Unix, dal campo deadline, sigDeadline o validBefore. |
eip712 |
Record |
No | Il payload EIP-712 strutturato: primary_type, domain e message, con numeri interi a 256 bit come stringhe in base 10. Solo EIP712_TYPED_DATA_V1. |
chain_id |
Long |
No | L'ID catena EVM, ad esempio 1 per Ethereum Mainnet o 11155111 per Sepolia. Solo Ethereum ed EIP-712. |
max_fee_atomic |
Long |
Sì | L'importo massimo che la transazione può pagare in commissioni di rete, in unità di 10-9 della moneta nativa della blockchain. 0 a EIP712_TYPED_DATA_V1. |
payload |
String |
Sì | Il digest con codifica esadecimale del payload, in minuscolo. |
time_stamp |
Long |
Sì | La createTime della transazione, in secondi dall'epoca di Unix. |
key_lists |
Record di Set<String> |
Sì | Un record che mappa ogni ID KeyList nell'istanza alla Set<String> di indirizzi blockchain in quel KeyList, risolto in createTime. Un record vuoto quando l'istanza non ha KeyList. Leggi un KeyList con la sintassi tra parentesi, ad esempio context.key_lists["trusted-destinations"]. Per saperne di più, consulta KeyList nel contesto di Cedar. |
principal_keyring e principal_key sono ID, non nomi completi delle risorse. Un ID chiave è univoco solo all'interno del relativo keyring. Seleziona principal_keyring per applicare una regola a ogni chiave in un KeyRing o entrambi gli attributi per assegnare un nome a una chiave:
context.principal_keyring == "treasury" && context.principal_key == "hot-wallet-1"
Se il payload non può essere decodificato dall'analizzatore per Transaction.schema o non può essere proiettato in un contesto, non viene valutata alcuna policy e la transazione viene negata con UNRECOGNIZED_PAYLOAD. Per saperne di più, consulta Motivi del rifiuto.
Nomi degli schemi
L'attributo schema è il nome del valore PayloadSchema nell'API v1beta: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" o "EIP712_TYPED_DATA_V1". I nomi in minuscolo utilizzati dalle regole v1alpha1, come "ethereum.transaction.v2", non corrispondono mai in v1beta.
Una regola senza un controllo schema o blockchain si applica a ogni blockchain.
Per limitare una regola a una blockchain, seleziona schema.
Importi
amount_token_scaled e max_fee_atomic utilizzano la stessa scala per ogni asset:
1 unità corrisponde a 10-9 dell'asset, quindi 1,0 di qualsiasi asset corrisponde a 1000000000.
Per ottenere il valore di una regola, moltiplica l'importo per 1.000.000.000 (109). La seguente tabella mostra alcuni esempi:
| Importo | amount_token_scaled |
|---|---|
| 0,1 ETH | 100000000 |
| 1,0 ETH, 1,0 BTC, 1,0 SOL o 1,0 USDC | 1000000000 |
| 0,0025 BTC (250.000 satoshi) | 2500000 |
| 1,5 SOL (1.500.000.000 lamport) | 1500000000 |
| 5000 USDC | 5000000000000 |
Per gli asset con più di 9 cifre decimali, come ETH, la parte dell'importo inferiore a 10-9 viene eliminata. Una regola non può controllarlo.
Ethereum
La tabella seguente descrive gli attributi di contesto per i payload ETHEREUM_TX_V2 (transazioni legacy con codifica RLP ed EIP-2718, incluso EIP-1559):
| Attributo | Valore |
|---|---|
secondary_key |
Per i trasferimenti di ETH e le chiamate di contratto, l'indirizzo to della transazione. Per ERC-20 transfer e transferFrom, ed ERC-721 transferFrom e safeTransferFrom, il destinatario del token o dell'NFT. Per ERC-20 ed ERC-721 approve, il pagatore approvato. Per ERC-721 setApprovalForAll, l'operatore. In formato checksum EIP-55 con lettere maiuscole e minuscole. |
amount_token_scaled |
Per i trasferimenti di ETH e i trasferimenti e le approvazioni di ERC-20, l'importo. Per le chiamate di contratto, gli ETH inviati con la chiamata; omesso se non vengono inviati ETH. Sempre omesso per i trasferimenti e le approvazioni ERC-721, in modo che i limiti di spesa fungibili non corrispondano agli ID token NFT. |
token_symbol |
"ETH" per i trasferimenti di ETH e per le chiamate di contratto che inviano ETH. Per i token ERC-20 riconosciuti su Ethereum Mainnet, "USDC", "USDT", "DAI" o "WBTC"; omesso per altri token e per le operazioni ERC-721. |
contract_address |
Per i trasferimenti e le approvazioni ERC-20 ed ERC-721, il contratto del token o dell'NFT. Per le chiamate di contratto, il contratto chiamato. In formato checksum EIP-55 con lettere maiuscole e minuscole. Omesso per i trasferimenti di ETH. |
token_standard |
"ERC721" per i trasferimenti e le approvazioni ERC-721. Omesso per i trasferimenti di ETH, le operazioni ERC-20 e altre chiamate di contratto. |
token_id |
Per ERC-721 transferFrom, safeTransferFrom e approve, il tokenId a 256 bit come String in base 10, in modo che gli ID NFT non superino mai il Long a 64 bit di Cedar. Poiché si tratta di un String, confrontalo per l'uguaglianza con == o in [...]; < e > confrontano stringhe, non numeri. Omesso per setApprovalForAll e per le transazioni che non sono ERC-721. |
from_address |
Per ERC-721 transferFrom e safeTransferFrom, il proprietario attuale (from), nel formato di checksum EIP-55 con lettere maiuscole e minuscole. |
approve_all |
Per ERC-721 setApprovalForAll(operator, approved), il flag approved come Bool: true quando concedi l'approvazione dell'operatore su ogni NFT della raccolta, false quando la revochi. |
chain_id |
L'ID catena della transazione. Può essere omesso nelle transazioni legacy, quindi controllalo con has. |
max_fee_atomic |
Limite di gas × tariffa massima per gas (o prezzo del gas per le transazioni legacy), in gwei. |
Per ERC-20 transfer(address, uint256) (0xa9059cbb), il cui selettore è univoco per ERC-20, un token non riconosciuto dal calcolo multipartitico ha un importo scalato come se il token avesse 18 cifre decimali. Abbina i token riconosciuti per contract_address e non impostare limiti di importo per i token non riconosciuti i cui decimali non sono 18. ERC-20 transferFrom e approve condividono i loro selettori con ERC-721, quindi hanno bisogno di un contratto riconosciuto; una chiamata a un contratto non riconosciuto con uno di questi selettori viene negata con UNRECOGNIZED_PAYLOAD. Per saperne di più, consulta Token non fungibili ERC-721.
Il contesto non specifica il tipo di transazione Ethereum, quindi tieni presente quanto segue:
- Le chiamate di contratto che inviano ETH sembrano trasferimenti di ETH. Entrambi hanno
token_symbol"ETH"e unamount_token_scaled. Solo una chiamata di contratto hacontract_address. Per consentire solo i trasferimenti di ETH, aggiungi!(context has contract_address). - Le approvazioni ERC-20 sembrano trasferimenti ERC-20. Un
approveha gli stessicontract_address,amount_token_scaledesecondary_key(il pagatore) di un trasferimento dello stesso importo allo stesso indirizzo. Una policy che consente il trasferimento consente anche l'approvazione.
Le transazioni di creazione di contratti (con un indirizzo to vuoto) non possono essere decodificate e vengono rifiutate con UNRECOGNIZED_PAYLOAD.
Non-fungible token ERC-721
In ETHEREUM_TX_V2, il calcolo multipartitico decodifica i seguenti metodi 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)
ERC-20 ed ERC-721 condividono gli stessi selettori a 4 byte per transferFrom
(0x23b872dd) e approve (0x095ea7b3). Per decidere se l'argomento uint256
è un importo fungibile o un ID token, il calcolo multipartitico cerca l'indirizzo del contratto to nel suo registro dei contratti token riconosciuti. Per le chiamate ERC-721, amount_token_scaled viene omesso, token_standard è "ERC721" e token_id è un String in base 10. Una chiamata a un contratto non riconosciuto con uno di questi selettori condivisi viene rifiutata con UNRECOGNIZED_PAYLOAD.
Dati tipizzati EIP-712
Per i payload EIP712_TYPED_DATA_V1 (dati digitati EIP-712 con codifica JSON UTF-8 con types, primaryType, domain e message), il calcolo multipartitico convalida la struttura JSON e calcola il digest di firma EIP-712 a 32 byte, keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)), dove ++ è la concatenazione di byte. La convalida rifiuta la nidificazione più profonda di 15 livelli, i tipi ciclici, gli elementi dell'array null e i campi domain che non corrispondono a types.EIP712Domain e conserva i numeri interi a 256 bit senza perdita di precisione nella rappresentazione in virgola mobile.
Un payload EIP712_TYPED_DATA_V1 proietta i seguenti attributi:
| Attributo | Valore |
|---|---|
blockchain |
Sempre "ETH". |
schema |
Sempre "EIP712_TYPED_DATA_V1". |
contract_address |
domain.verifyingContract, in formato checksum EIP-55 con lettere maiuscole e minuscole. Omesso quando il dominio non imposta verifyingContract. |
chain_id |
domain.chainId come Long. Omesso quando il dominio non imposta chainId. |
max_fee_atomic |
Sempre 0, perché la firma dei dati digitati non prevede una commissione di rete. |
secondary_key |
Per i tipi di messaggi riconosciuti, la controparte: spender per ERC-2612 Permit e Uniswap Permit2 o to per ERC-3009 TransferWithAuthorization e Safe SafeTx. Per altri tipi di messaggi, domain.verifyingContract. |
amount_token_scaled |
Per i tipi di messaggi riconosciuti (Permit, Permit2, TransferWithAuthorization e SafeTx), il token autorizzato o il valore ETH (value o details.amount), in unità di 10-9. Omesso per altri tipi di messaggi. |
token_symbol |
"USDC", "USDT", "DAI" o "WBTC" quando il contratto di verifica o il token Permit2 (details.token) è un token riconosciuto sulla rete principale di Ethereum. In caso contrario, viene omesso. |
deadline |
La scadenza del messaggio, in secondi dall'epoca di Unix, quando il messaggio contiene un campo deadline, sigDeadline o validBefore. In caso contrario, viene omesso. |
eip712 |
Un Record con i dati digitati. Per saperne di più, consulta la tabella seguente. |
Il record eip712 contiene i seguenti campi:
| Campo | Tipo di cedro | Valore |
|---|---|---|
context.eip712.primary_type |
String |
Il nome primaryType, ad esempio "Permit", "PermitSingle", "TransferWithAuthorization" o "SafeTx". |
context.eip712.domain |
Record |
I campi EIP712Domain impostati dal payload: name, version, chainId, verifyingContract e salt. |
context.eip712.message |
Record |
I campi message. I valori interi a 256 bit (uint256 e int256) sono String in base 10, pertanto le regole possono corrispondere a valori esatti senza overflow a 64 bit. |
Bitcoin
La seguente tabella descrive gli attributi di contesto per i payload BITCOIN_TX_V2 (BIP 174 PSBT v0):
| Attributo | Valore |
|---|---|
secondary_key |
L'indirizzo dell'unico output che non è il resto. Per un consolidamento, in cui ogni output è un resto, l'indirizzo del primo output. |
amount_token_scaled |
L'importo inviato a secondary_key, senza contare il resto (1 satoshi = 10). 0 per un consolidamento. |
token_symbol |
Sempre "BTC". |
contract_address |
Non è mai presente. |
chain_id |
Non è mai presente, perché una PSBT non indica la rete a cui è destinata. Gli indirizzi sono sempre formattati come indirizzi Mainnet, quindi anche un indirizzo Testnet inizia con bc1, 1 o 3. Il prefisso dell'indirizzo mostra il tipo di indirizzo, non la rete. |
max_fee_atomic |
La commissione per il miner: input totali meno output totali (1 satoshi = 10). |
Per mantenere separate le reti Bitcoin, utilizza chiavi diverse per ogni rete, ad esempio in un KeyRing per Mainnet e un altro per Testnet, e applica regole di ambito con principal_keyring o principal_key. La stessa chiave può firmare su entrambe le reti, quindi questo funziona solo se non utilizzi mai una chiave Mainnet su Testnet.
Una transazione che invia a più di un indirizzo che non è di resto non può essere decodificata. Una transazione senza indirizzo di destinazione, ad esempio una il cui unico output che non è un resto è un output OP_RETURN, non può essere valutata.
Solana
La tabella seguente descrive gli attributi di contesto per i payload SOLANA_TX_V1 (messaggi Solana legacy non firmati o v0):
| Attributo | Valore |
|---|---|
secondary_key |
Per i trasferimenti di SOL, il wallet di destinazione. Per i trasferimenti di token, l'account del token di destinazione, non il wallet proprietario. In base58. |
amount_token_scaled |
L'importo. Per SOL, il numero di lamport (1 lamport = 1). Per i token, l'importo non elaborato scalato con i decimali contenuti nell'istruzione TransferChecked. |
token_symbol |
"SOL" per i trasferimenti di SOL. Per i token, "USDC", "USDT" o "PYUSD"; omesso per altri mint. |
contract_address |
Per i trasferimenti di token, l'indirizzo di minting, in base58. Omesso per i trasferimenti SOL. |
chain_id |
Non è mai presente. I messaggi Solana non indicano un cluster. |
max_fee_atomic |
L'importo massimo che l'intera transazione può pagare in lamport: 5000 per ogni firma richiesta, più la commissione di priorità, ⌈limite di unità di calcolo × prezzo dell'unità di calcolo in micro-lamport ÷ 106⌉, se la transazione imposta un prezzo dell'unità di calcolo. |
Una transazione Solana può contenere diverse istruzioni:
- Istruzioni per il trasferimento: programma di sistema
Transfer(SOL) e token SPL o Token-2022TransferChecked. L'istruzioneTransfernon selezionata e i token con più di 9 cifre decimali non possono essere decodificati. - Altre istruzioni: ComputeBudget
SetComputeUnitLimiteSetComputeUnitPrice, Memo (v1 e v2), Associated Token AccountCreateeCreateIdempotente System ProgramAdvanceNonceAccount. Queste istruzioni non producono un contesto proprio.
Ogni istruzione di trasferimento viene valutata separatamente con il proprio contesto. La transazione è consentita solo se ogni trasferimento è consentito; se un trasferimento viene negato, l'intera transazione viene negata. max_fee_atomic è la commissione per l'intera transazione ed è la stessa in ogni contesto, quindi non sommarla ai trasferimenti.
Se la transazione imposta un prezzo per unità di calcolo senza un limite di unità di calcolo, la commissione utilizza il limite predefinito di Solana di 200.000 unità di calcolo per ogni istruzione diversa dalle istruzioni ComputeBudget, fino a 1.400.000.
I firmatari della transazione devono corrispondere agli account che ogni istruzione deve firmare e gli account di origine e l'account di destinazione devono essere scrivibili. I messaggi v0 che utilizzano tabelle di ricerca degli indirizzi non possono essere decodificati. Passa i byte del messaggio non firmato, non una busta della transazione firmata, in Transaction.payload e Transaction.rawMessage.
I mint riconosciuti sono quelli della mainnet di Solana. Su Devnet o Testnet, un trasferimento di token non ha token_symbol, quindi controlla contract_address.
Un'istruzione Associated Token Account Create finanzia la riserva esente da affitto del nuovo account in SOL. Questo importo non è in amount_token_scaled.
Regole di esempio
Di seguito sono riportati esempi di policy permit e forbid che puoi adattare.
Ogni esempio controlla ogni attributo facoltativo con has prima di leggerlo.
Limite di acquisto per un keyring che utilizza payload e metadati
Consenti i trasferimenti buy_transaction fino a 500.000 USDC su Ethereum Mainnet
da qualsiasi chiave nel keyring institutional-treasury, quando l'iniziatore
etichetta la transazione con "equities-desk", imposta una validità massima di 300
secondi e dichiara un valore massimo di 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"
};
Il calcolo multipartitico non controlla fiat_amount rispetto al payload. Per saperne di più, consulta Attributi di contesto.
Limite di spesa per una chiave
Consenti trasferimenti di ETH fino a 1 ETH da una chiave su Ethereum Mainnet.
!(context has contract_address) esclude le chiamate di contratto che inviano 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 consentita di stablecoin su Ethereum
Consenti trasferimenti fino a 5000 USDC a un indirizzo e approvazioni (autorizzazioni) fino a 5000 USDC per quell'indirizzo. La policy controlla
contract_address anziché token_symbol, quindi un token di un altro
contratto che utilizza lo stesso simbolo non corrisponde:
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" per questa transazione.
Protezione per il trasferimento ERC-721 e l'approvazione dell'operatore
Consenti il trasferimento di un titolo del Tesoro tokenizzato (token_id == "1042") da un contratto ERC-721 approvato a un indirizzo di liquidazione e vieta la concessione di approvazioni dell'operatore a livello di raccolta (setApprovalForAll con approve_all == true).
La norma A consente il trasferimento di 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 policy B vieta le approvazioni degli operatori a livello di raccolta:
forbid (principal, action, resource)
when {
context.schema == "ETHEREUM_TX_V2" &&
context has approve_all && context.approve_all == true
};
Limite di autorizzazione USDC senza gas EIP-712
Autorizza la firma di un ERC-2612 Permit off-chain per un massimo di 25.000 USDC su Ethereum Mainnet per un router di liquidazione approvato, quando l'autorizzazione scade prima di un determinato momento:
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 di spesa e limite di commissione per Bitcoin
Consenti trasferimenti fino a 0,0025 BTC con una commissione per i miner fino a 10.000 satoshi, dalle chiavi di un KeyRing che utilizzi solo su 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 di trasferimento e commissione prioritaria di SOL
Consenti trasferimenti di SOL fino a 1,5 SOL quando la commissione totale, inclusa l'eventuale commissione di priorità, è al massimo di 50.000 lamport (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
};
Trasferimento di token SPL o Token-2022 su Solana
Consenti trasferimenti fino a 250 USDC a un account token. La stessa regola corrisponde ai programmi SPL Token e Token-2022, perché il contesto non indica quale programma utilizza il trasferimento:
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 è l'account token del destinatario per questo mint. Per consentire un portafoglio destinatario, elenca il relativo account token per ogni mint che consenti. In una transazione con più trasferimenti, questa regola deve corrispondere a ogni trasferimento.
Blocco di asset non riconosciuto
Rifiuta qualsiasi trasferimento la cui risorsa non è riconosciuta dal calcolo multipartitico. Questa policy forbid utilizza solo has, pertanto la valutazione non può non riuscire:
forbid (principal, action, resource)
when { context has amount_token_scaled }
unless { context has token_symbol };
Limite di commissione per una blockchain
max_fee_atomic è sempre presente, quindi questa policy forbid non può non essere valutata. Poiché la scala è 10-9 di ogni moneta nativa, lo stesso numero ha un valore diverso su ogni blockchain. Definisci l'ambito della policy per una blockchain:
forbid (principal, action, resource)
when { context.blockchain == "ETH" && context.max_fee_atomic > 10000000 };
In questo modo, vengono negate le transazioni Ethereum che possono pagare più di 0,01 ETH di commissioni.
KeyRing
Un KeyRing è un container statico che raggruppa le chiavi MPC, ad esempio "institutional-treasury" o "btc-cold-storage". Ogni chiave viene creata all'interno di un singolo keyring e rimane in quel keyring in modo permanente.
I keyring partecipano alle policy in tre modi:
- KeyRing
KeyPolicy(quorum di firma). Quando crei un KeyRing, imposti la sua KeyPolicy immutabile, che definisce l'albero di soglia dei team e degli utenti che detengono le condivisioni delle chiavi e devono approvare prima che qualsiasi chiave nel KeyRing possa firmare. Le policy delle transazioni funzionano insieme allaKeyPolicy: la policy delle transazioni valuta le regole aziendali per il payload (PERMIToDENY), mentre laKeyPolicydel KeyRing stabilisce quali condivisioni di chiavi devono autorizzare la cerimonia di firma. Definizione dell'ambito delle policy di transazione in base al keyring di firma (
context.principal_keyring). Il contesto di ogni transazione includecontext.principal_keyring, impostato sull'ID del keyring che contiene la chiave di firma, econtext.principal_key, impostato sull'ID della chiave di firma. Una regola concontext.principal_keyring == "institutional-treasury"si applica a ogni chiave nel keyring, incluse quelle create successivamente, senza creare o approvare una nuova policy: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 consentita di KeyRing di destinazione (in un KeyList). Puoi anche aggiungere un KeyRing come voce in un KeyList, in modo che i trasferimenti all'indirizzo blockchain di qualsiasi chiave attiva in quel KeyRing, ad esempio gli sweep interni tra KeyRing hot e cold, siano consentiti automaticamente man mano che vengono create nuove chiavi. Per un esempio, consulta Lista consentita e lista bloccata di KeyList.
Lista consentita e lista bloccata KeyList
Consenti trasferimenti fino a 1 ETH solo agli indirizzi nel KeyList trusted-destinations. context.key_lists["trusted-destinations"] è l'insieme di indirizzi
in cui KeyList si espande in corrispondenza di createTime della transazione, pertanto l'aggiunta o
la rimozione di una voce modifica ciò che questa regola consente senza una nuova policy:
// 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
};
Nega qualsiasi transazione a un indirizzo nell'elenco di chiavi blocked-addresses, su ogni blockchain. key_lists e secondary_key sono sempre presenti e CreateTransactionPolicy verifica che KeyList esista, quindi questa policy forbid non può non essere valutata:
// Assuming you created a KeyList with ID "blocked-addresses":
forbid (principal, action, resource)
when { context.key_lists["blocked-addresses"].contains(context.secondary_key) };
Scrivi l'ID KeyList nella sintassi tra parentesi, context.key_lists["..."], anziché nella sintassi con punto. La sintassi con punto non riesce ad analizzare gli ID che contengono un trattino o iniziano con una cifra. Le voci vengono confrontate come stringhe, quindi aggiungi voci manuali nel formato dell'indirizzo descritto dalla tabella per ogni blockchain. Per saperne di più, consulta KeyList nel contesto Cedar.