Questa pagina descrive come creare regole delle policy Cedar per convalidare le transazioni nel Policy Engine di calcolo multipartitico (MPC).
Il Policy Engine decodifica i payload delle transazioni in entrata all'interno di un Trusted Execution Environment (TEE) sicuro e proietta gli attributi dell'intent della transazione nel contesto di valutazione di Cedar.
Struttura delle regole Cedar
Quando scrivi regole Cedar per il Policy Engine, specifichi una regola utilizzando un insieme nidificato di condizioni:
- Principal: l'identità logica del richiedente della transazione (l'iniziatore della transazione) all'interno dello spazio di lavoro di calcolo multipartitico (ad esempio
User::"alice"), anziché l'identità IAM Google Cloud (utente o account di servizio) che chiama l'API. - Action: l'azione crittografica richiesta (ad esempio
Action::"sign_transaction"). - Risorsa: l'asset o la classe di operazioni di destinazione su cui viene eseguita l'operazione (ad esempio
Resource::"mpc_operation"). - Contesto: i parametri e i metadati della transazione analizzati (accessibili in
context.transaction).
Riferimento allo schema delle transazioni Ethereum
Il framework indipendente dal protocollo consente alle regole di omettere il controllo dello schema per rimanere riutilizzabili su diverse reti blockchain. Tuttavia, per limitare esplicitamente una regola ai payload delle transazioni Ethereum, seleziona: context.transaction.schema == "ethereum.transaction.v2".
I seguenti attributi sono supportati all'interno del record context.transaction:
| Attributo | Tipo | Descrizione |
|---|---|---|
schema |
Stringa | Lo schema del formato. Per le transazioni Ethereum, questo valore è sempre "ethereum.transaction.v2". |
operation |
Stringa |
Il tipo di operazione della transazione. Valori supportati:
|
chain_id |
Stringa | L'ID della rete blockchain di destinazione (ad esempio, "1" per Ethereum Mainnet o "11155111" per Sepolia Testnet). |
asset_symbol |
Stringa | Il simbolo del ticker del token trasferito (ad esempio, "ETH", "USDC", "DAI" o "WBTC"). I token non in elenco restituiscono "UNKNOWN". |
asset_contract_address |
Stringa | L'indirizzo dello smart contract del token ERC-20 (nel formato di checksum EIP-55 con lettere maiuscole e minuscole). Per i trasferimenti ETH standard, il risultato è una stringa vuota (""). |
recipient |
Stringa | L'indirizzo del destinatario (nel formato di checksum EIP-55 con lettere maiuscole e minuscole). Per le approvazioni dei token, rappresenta l'indirizzo di chi spende. |
spend_amount_scaled |
Lungo |
L'importo del trasferimento di token normalizzato a una precisione fissa di 9 decimali (formato nanocoin), eliminando la necessità di monitorare i decimali dei token variabili (ad esempio 6, 8 o 18) durante la scrittura delle regole.
Come calcolare: moltiplica l'importo dell'asset leggibile (ad es. 1,5 ETH o 5000 USDC) per 1.000.000.000 (109) per ottenere il valore della regola:
|
spend_amount_dust |
Lungo | Il resto dell'importo della transazione che scende al di sotto della soglia di precisione di 9 decimali. Per gli asset con più di 9 decimali (come ETH, che ne ha 18), questo campo contiene il valore sub-Gwei non scalato (i Wei rimanenti). Questo valore è sempre 0 per gli asset con 9 o meno decimali (come USDC o WBTC). |
max_fee_atomic |
Lungo | Il limite massimo della commissione di transazione totale (scalato di 109, che rappresenta Gwei). |
gas_limit |
Lungo | La quantità massima di gas allocata per l'esecuzione della transazione. |
destination_type |
Stringa | La classificazione dell'indirizzo del destinatario. Valori supportati: "EOA" (portafoglio utente standard), "CONTRACT" (smart contract) o "INTERNAL_TREASURY" (un vault interno). |
temporal_validity |
Lungo | Il nonce dell'account della transazione (utilizzato per prevenire attacchi di replay delle transazioni). |
Riferimento allo schema delle transazioni Bitcoin
Per limitare esplicitamente una regola ai payload delle transazioni PSBT Bitcoin BIP 174, seleziona: context.transaction.schema == "bitcoin.transaction.v2".
I seguenti attributi sono supportati all'interno del record context.transaction:
| Attributo | Tipo | Descrizione |
|---|---|---|
schema |
Stringa | Lo schema del formato. Per le transazioni in Bitcoin, il valore è sempre "bitcoin.transaction.v2". |
operation |
Stringa |
Il tipo di operazione della transazione. Valori supportati:
|
chain_id |
Stringa | La parte leggibile (HRP) Bech32 della rete di destinazione: "bc" (Bitcoin Mainnet), "tb" (Testnet / Testnet4) o "bcrt" (Regtest). |
asset_symbol |
Stringa | Il simbolo ticker dell'asset: "BTC". |
recipient |
Stringa | L'indirizzo di destinazione principale. Per le transazioni OP_RETURN, questo valore è "unaddressable". Per i sweep di consolidamento interno (modifica del 100%), questo si risolve nel primo indirizzo di modifica. |
spend_amount_scaled |
Lungo |
L'importo netto del trasferimento in uscita normalizzato con precisione fissa a 9 decimali (10-9 unità). Poiché 1 satoshi equivale a 10 unità di nanocoin (1 sat = 10 unità, 1 BTC = 109 unità), gli importi dei resti interni sono esclusi. Per le transazioni di sweep interno / resto del 100%, il valore è 0.
|
max_fee_atomic |
Lungo | Il limite della commissione per i miner calcolato normalizzato con precisione a 9 decimali: (∑ Input − ∑ Output) × 10. |
destination_type |
Stringa | La classificazione dello script del destinatario. Valori supportati: "P2WPKH" (SegWit nativo), "P2TR" (Taproot), "P2PKH" (Legacy), "P2SH" (SegWit nidificato / Script Hash), "TREASURY_CHANGE" (sweep di modifica interno) o "". |
temporal_validity |
Lungo | Il campo nLockTime della transazione. |
outputs |
Set<Record> | L'insieme normalizzato di tutti gli output delle transazioni: [{ address: String, amount_scaled: Long, is_change: Bool }]. |
Concetti principali delle norme relative a Bitcoin
Calcolo della scalabilità universale a 9 decimali: Gli importi nelle policy Bitcoin utilizzano una precisione normalizzata a 9 decimali (1 sat = 10 unità, 1 BTC = 109 unità):
Importoscalato = Satoshis × 10 = BTC × 109
0.0005BTC (50.000 satoshi) →500000(50.000 × 10)0.0025BTC (250.000 satoshi) →2500000(250.000 × 10)1.0BTC (100.000.000 satoshi) →1000000000(100.000.000 × 10)
Separazione degli output di resto: il parser esamina i percorsi di derivazione BIP-32 (
m/.../1/*) e mette in correlazione gli script di input per identificare automaticamente gli output di resto interni. Gli importi dei resti sono esclusi daspend_amount_scaled, garantendo che le policy relative ai limiti di spesa vengano valutate rigorosamente in base al valore netto in uscita trasferito a terze parti.Regola per un singolo destinatario non di resto: per evitare attacchi di routing ambigui con più destinatari, le transazioni contenenti più destinatari esterni di terze parti distinti non vengono eseguite (
ErrUnsupportedTx).
Esempi di regole Cedar
Gli esempi seguenti mostrano come configurare liste consentite, regole di limite e limiti di replay utilizzando Cedar per le transazioni Ethereum e Bitcoin.
Esempi di Ethereum
Le seguenti regole illustrano i pattern delle policy comuni per le transazioni Ethereum ed ERC-20.
1. Limite di trasferimento diretto di ETH
Questa regola consente ad Alice di trasferire ETH della catena di base, verificando che l'importo del trasferimento scalato non superi 1,0 ETH (1.000.000.000 di unità Gwei scalate).
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.operation == "NATIVE_TRANSFER" &&
context.transaction.asset_symbol == "ETH" &&
context.transaction.spend_amount_scaled <= 1000000000
};
2. Regola della lista consentita dei token ERC-20
Questa regola consente i trasferimenti di token USDC fino a 5000 USDC. Limita i trasferimenti a un indirizzo del destinatario presente in una lista consentita. Tieni presente che, poiché le stringhe Cedar sono sensibili alle maiuscole, l'indirizzo del destinatario deve corrispondere al formato EIP-55 con maiuscole e minuscole.
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.operation == "TOKEN_TRANSFER" &&
context.transaction.asset_symbol == "USDC" &&
context.transaction.recipient == "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" &&
context.transaction.spend_amount_scaled <= 5000000000000
};
3. Fallback delle chiamate DeFi e degli smart contract
Questa regola consente interazioni generali con i contratti (come staking o scambio) senza limitazioni di importo, a condizione che non si tratti di operazioni di trasferimento di asset.
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.operation == "CONTRACT_CALL"
};
4. Protezione di riproduzione rigorosa (limite ID catena)
Per evitare attacchi di replay delle transazioni in cui un payload firmato per una catena testnet viene inviato nuovamente su mainnet di produzione, puoi limitare l'ambito della regola a un ID catena specifico (ad es. 11155111 per Sepolia).
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.chain_id == "11155111"
};
Esempi di Bitcoin
Le seguenti regole illustrano i pattern di policy comuni per le transazioni PSBT di Bitcoin.
1. Limite di spesa e limite della commissione per i miner
Questa regola consente i trasferimenti diretti di Bitcoin (BTC) in cui l'importo netto del trasferimento in uscita non supera 0,0025 BTC (250.000 satoshi → 2.500.000 unità scalate) e la commissione del miner non supera 10.000 satoshi (100.000 unità atomiche).
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.operation == "NATIVE_TRANSFER" &&
context.transaction.asset_symbol == "BTC" &&
context.transaction.spend_amount_scaled <= 2500000 &&
context.transaction.max_fee_atomic <= 100000
};
2. Lista consentita di indirizzi SegWit (P2WPKH) e Taproot (P2TR)
Questa regola limita i trasferimenti di Bitcoin a un indirizzo di destinazione SegWit o Taproot approvato.
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.schema == "bitcoin.transaction.v2" &&
(context.transaction.destination_type == "P2WPKH" || context.transaction.destination_type == "P2TR") &&
context.transaction.recipient == "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
};
3. Consolidamento UTXO e sweep della tesoreria
Questa regola consente le operazioni di consolidamento UTXO interne in cui tutti gli output tornano agli indirizzi di resto interni (destination_type == "TREASURY_CHANGE" e spend_amount_scaled == 0), limitando al contempo la commissione di consolidamento.
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.schema == "bitcoin.transaction.v2" &&
context.transaction.destination_type == "TREASURY_CHANGE" &&
context.transaction.spend_amount_scaled == 0 &&
context.transaction.max_fee_atomic <= 50000
};
4. Ispezione del set di output
Questa regola convalida che il set di output della transazione contenga un output e un importo di destinazione specifici.
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.outputs.contains({
address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
amount_scaled: 500000,
is_change: false
})
};
5. Ambito della rete (Mainnet e Testnet)
Questa regola limita l'autorizzazione alle transazioni Bitcoin Testnet (tb), impedendo l'esecuzione su Bitcoin Mainnet (bc).
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.schema == "bitcoin.transaction.v2" &&
context.transaction.chain_id == "tb"
};
6. Ancoraggio dei dati di OP_RETURN
Questa regola consente transazioni di ancoraggio dei dati OP_RETURN non spendibili (spend_amount_scaled == 0 e recipient == "unaddressable"), applicando un limite rigoroso alle commissioni.
permit (
principal == User::"alice",
action == Action::"sign_transaction",
resource == Resource::"mpc_operation"
)
when {
context.transaction.operation == "OP_RETURN" &&
context.transaction.recipient == "unaddressable" &&
context.transaction.spend_amount_scaled == 0 &&
context.transaction.max_fee_atomic <= 10000
};
Difese di sicurezza del parser
Per salvaguardare le operazioni di transazione negli ambienti di produzione, il Policy Engine analizza i payload in modo rigoroso e rifiuta le strutture non valide a livello di gateway prima di valutare qualsiasi regola Cedar:
- Applicazione della valuta di base con valore zero:il parser rifiuta esplicitamente le operazioni di trasferimento di token Ethereum (
TOKEN_TRANSFER) che tentano anche di raggruppare asset di trasferimento di base diversi da zero. In questo modo, i payload dannosi non possono trasferire valori di asset di base standard, presentando al contempo la transazione come un trasferimento di token standard. - Verifica di UTXO e Witness: per le transazioni PSBT di Bitcoin, l'analizzatore convalida che tutti gli input forniscano dati
witness_utxovalidi, impedendo lo spoofing del calcolo delle commissioni o la firma non verificata. - Verifica dello script di output di resto: gli output di resto interni devono corrispondere a una chiave pubblica dello script di input o a un percorso di resto BIP-32 noto (
m/.../1/*). I payload che tentano di falsificare gli output di resto verso indirizzi di terze parti non vengono eseguiti. - Applicazione di un singolo destinatario esterno: i payload Bitcoin contenenti più indirizzi di destinazione esterni non di resto non vengono chiusi (
ErrUnsupportedTx) per impedire l'autorizzazione di policy ambigue per più destinatari. - Protezione da overflow e underflow di numeri interi: i nonce, i locktime, i limiti di gas o commissioni e gli importi che superano i limiti di sicurezza (
MaxInt64) o producono underflow (ad esempio, il valore di output totale che supera il valore di input totale) vengono immediatamente rifiutati. - Verifica delle commissioni mancante: le transazioni che non definiscono le commissioni per i miner o i parametri del gas appropriati non vengono eseguite automaticamente.