Regeln für Transaktionsrichtlinien schreiben

Auf dieser Seite werden die Attribute beschrieben, die eine Transaktionsrichtlinie prüfen kann. Außerdem finden Sie hier Beispielregeln für Ethereum- (ETHEREUM_TX_V2 und EIP712_TYPED_DATA_V1), Bitcoin- (BITCOIN_TX_V2) und Solana-Transaktionen (SOLANA_TX_V1).

Informationen dazu, wie Richtlinien kombiniert werden, welche Richtlinien erzwungen werden und warum eine Transaktion abgelehnt wird, finden Sie unter Auswertung von Transaktionsrichtlinien.

Regelstruktur

Eine Transaktionsrichtlinie ist eine einzelne Cedar-Anweisung vom Typ permit oder forbid, die sich auf das Hauptkonto, die Aktion, die Ressource und den Kontext bezieht:

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
};

Beachten Sie Folgendes:

  • Attribute befinden sich auf der obersten Ebene des Kontexts. Schreiben Sie context.amount_token_scaled, nicht context.transaction.spend_amount_scaled wie in v1alpha1.
  • Einige Attribute sind optional. Ein optionales Attribut, das nicht im Kontext enthalten ist, führt dazu, dass die Richtlinie nicht ausgewertet werden kann. Eine Richtlinie, die nicht ausgewertet werden kann, stimmt nicht überein. Prüfen Sie, ob ein optionales Attribut mit has vorhanden ist, bevor Sie es lesen, oder mit unless { context has ... } in einer forbid-Regel. Weitere Informationen finden Sie unter Szenario 6 und Szenario 8.
  • Bei Cedar-Strings wird zwischen Groß- und Kleinschreibung unterschieden. Vergleichen Sie die Adressen im Format, das in der Tabelle für die jeweilige Kette beschrieben ist.

Informationen zum Hauptkonto finden Sie unter Die Cedar-Anfrage. Informationen zu den Aktionen, die CreateTransaction akzeptiert (buy_transaction, sell_transaction und internal_transfer_transaction), finden Sie unter Aktion und Ressource.

Kontextattribute

Der Kontext jeder Transaktion enthält die aus der Nutzlast decodierten Attribute, die IDs des Signaturschlüssels und seines KeyRings sowie die vom Initiator festgelegten Metadatenattribute (fiat_amount, validity, principal_value1 und principal_value2).

Die Nutzlastattribute sind für jede Blockchain gleich. In der folgenden Tabelle werden alle Kontextattribute beschrieben. In den Tabellen für Ethereum, Bitcoin und Solana wird beschrieben, wie die Multi-Party Computation die einzelnen Attribute für die jeweilige Blockchain füllt:

Attribut Cedar-Typ Immer vorhanden? Wert
schema String Ja Das Nutzlastformat: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" oder "EIP712_TYPED_DATA_V1". Weitere Informationen finden Sie unter Schemanamen.
blockchain String Ja "ETH", "BTC" oder "SOL".
principal_keyring String Ja Die ID des Schlüsselbunds, der den Signaturschlüssel enthält, z. B. "treasury".
principal_key String Ja Die ID des Signaturschlüssels, z. B. "hot-wallet-1".
secondary_key String Ja Die Zieladresse, der Token- oder NFT-Empfänger, der genehmigte Spender oder Betreiber oder die EIP-712-Gegenpartei, die aus der Nutzlast decodiert wurde.
amount_token_scaled Long Nein Der übertragene oder genehmigte fungible Betrag in Einheiten von 10-9 des Assets. Wird weggelassen, wenn kein fungibler Betrag übertragen wird, z. B. bei einem ERC-721-Vorgang oder einem Vertragsaufruf, bei dem keine ETH gesendet werden. Weitere Informationen finden Sie unter Beträge.
token_symbol String Nein Das Symbol des Assets, z. B. "ETH", "BTC", "SOL" oder "USDC". Wird weggelassen, wenn das Asset nicht von Multi-Party Computation erkannt wird, und für ERC-721-Vorgänge.
contract_address String Nein Der ERC-20- oder ERC-721-Token-Vertrag oder der aufgerufene Vertrag (Ethereum), der Verifizierungsvertrag (EIP-712) oder die Mint (Solana). Wird bei nativen Übertragungen weggelassen.
token_standard String Nein "ERC721" für ERC-721-Übertragungen und -Genehmigungen (ETHEREUM_TX_V2). Wird bei nativen Übertragungen und Vorgängen mit fungiblen Tokens weggelassen.
token_id String Nein Die 256-Bit-ERC-721-tokenId als String zur Basis 10 (ETHEREUM_TX_V2). Wird für setApprovalForAll und für Transaktionen, die nicht ERC-721 sind, weggelassen.
from_address String Nein Der aktuelle Inhaber (from) in ERC-721-transferFrom- und safeTransferFrom-Aufrufen im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung.
approve_all Bool Nein Das Flag approved in ERC-721-setApprovalForAll(operator, approved)-Aufrufen: true beim Erteilen der Betreibergenehmigung, false beim Widerrufen.
deadline Long Nein Die Ablaufzeit einer EIP712_TYPED_DATA_V1-Nachricht in Sekunden seit der Unix-Epoche, aus dem Feld deadline, sigDeadline oder validBefore.
eip712 Record Nein Die strukturierte EIP-712-Nutzlast: primary_type, domain und message mit 256-Bit-Ganzzahlen als Strings zur Basis 10. Nur EIP712_TYPED_DATA_V1.
chain_id Long Nein Die EVM-Chain-ID, z. B. 1 für Ethereum Mainnet oder 11155111 für Sepolia. Nur Ethereum und EIP-712.
max_fee_atomic Long Ja Der Höchstbetrag, der für die Transaktion an Netzwerkgebühren gezahlt werden kann, in Einheiten von 10-9 der nativen Coin der Blockchain. 0 für EIP712_TYPED_DATA_V1.
payload String Ja Der hexadezimal codierte Digest der Nutzlast in Kleinbuchstaben.
time_stamp Long Ja Der createTime der Transaktion in Sekunden seit der Unix-Epoche.
key_lists Record von Set<String> Ja Ein Eintrag, der jede KeyList-ID in der Instanz der Set<String> der Blockchain-Adressen in dieser KeyList zuordnet, aufgelöst um createTime. Ein leerer Eintrag, wenn die Instanz keine KeyLists hat. Lesen Sie eine KeyList mit Klammersyntax, z. B. context.key_lists["trusted-destinations"]. Weitere Informationen finden Sie unter KeyLists im Cedar-Kontext.

principal_keyring und principal_key sind IDs, keine vollständigen Ressourcennamen. Eine Schlüssel-ID ist nur innerhalb des zugehörigen Schlüsselbunds eindeutig. Aktivieren Sie principal_keyring, um eine Regel auf jeden Schlüssel in einem Schlüsselbund anzuwenden, oder beide Attribute, um einen Schlüssel zu benennen:

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

Wenn die Nutzlast vom Parser für Transaction.schema nicht decodiert oder nicht in einen Kontext projiziert werden kann, wird keine Richtlinie ausgewertet und die Transaktion wird mit UNRECOGNIZED_PAYLOAD abgelehnt. Weitere Informationen finden Sie unter Ablehnungsgründe.

Schemanamen

Das Attribut schema ist der Name des PayloadSchema-Werts in der v1beta API: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1" oder "EIP712_TYPED_DATA_V1". Die von v1alpha1-Regeln verwendeten Namen in Kleinbuchstaben, z. B. "ethereum.transaction.v2", stimmen in v1beta nie überein.

Eine Regel ohne schema- oder blockchain-Prüfung gilt für jede Blockchain. Wenn Sie eine Regel auf eine Blockchain beschränken möchten, setzen Sie ein Häkchen bei schema.

Beträge

amount_token_scaled und max_fee_atomic verwenden für jedes Asset dieselbe Skala: 1 Einheit entspricht 10-9 des Assets, also entspricht 1,0 eines Assets 1000000000. Um den Wert für eine Regel zu erhalten, multiplizieren Sie den Betrag mit 1.000.000.000 (109). Die folgende Tabelle enthält einige Beispiele:

Betrag amount_token_scaled
0,1 ETH 100000000
1,0 ETH, 1,0 BTC, 1,0 SOL oder 1,0 USDC 1000000000
0,0025 BTC (250.000 Satoshis) 2500000
1,5 SOL (1.500.000.000 Lamports) 1500000000
5.000 USDC 5000000000000

Bei Assets mit mehr als 9 Dezimalstellen, z. B. ETH, wird der Teil des Betrags, der kleiner als 10-9 ist, weggelassen. Eine Regel kann das nicht prüfen.

Ethereum

In der folgenden Tabelle werden die Kontextattribute für ETHEREUM_TX_V2-Nutzlasten (RLP-codierte Legacy- und EIP-2718-Transaktionen, einschließlich EIP-1559) beschrieben:

Attribut Wert
secondary_key Bei ETH-Übertragungen und Vertragsaufrufen die to-Adresse der Transaktion. Für ERC-20 transfer und transferFrom sowie ERC-721 transferFrom und safeTransferFrom der Token- oder NFT-Empfänger. Für ERC-20 und ERC-721 approve der genehmigte Spender. Für ERC-721 setApprovalForAll, der Operator. Im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung.
amount_token_scaled Bei ETH-Übertragungen sowie ERC-20-Übertragungen und -Genehmigungen den Betrag. Bei Vertragsaufrufen die mit dem Aufruf gesendeten ETH. Wird weggelassen, wenn keine ETH gesendet werden. Wird bei ERC-721-Übertragungen und -Genehmigungen immer weggelassen, damit die Ausgabenlimits für fungible Tokens nicht mit den NFT-Token-IDs übereinstimmen.
token_symbol "ETH" für ETH-Übertragungen und für Vertragsaufrufe, die ETH senden. Für anerkannte ERC-20-Tokens im Ethereum-Mainnet, "USDC", "USDT", "DAI" oder "WBTC"; wird für andere Tokens und für ERC-721-Vorgänge weggelassen.
contract_address Bei ERC-20- und ERC-721-Übertragungen und -Genehmigungen der Token- oder NFT-Vertrag. Bei Vertragsaufrufen der aufgerufene Vertrag. Im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung. Wird bei ETH-Übertragungen weggelassen.
token_standard "ERC721" für ERC-721-Übertragungen und -Genehmigungen. Wird bei ETH-Übertragungen, ERC-20-Vorgängen und anderen Vertragsaufrufen weggelassen.
token_id Für ERC-721 transferFrom, safeTransferFrom und approve wird die 256-Bit-tokenId als String zur Basis 10 verwendet, damit NFT-IDs nie die 64-Bit-Long von Cedar überschreiten. Da es sich um einen String handelt, vergleichen Sie ihn auf Gleichheit mit == oder in [...]. < und > vergleichen Strings, keine Zahlen. Wird für setApprovalForAll und für Transaktionen, die nicht ERC-721 sind, weggelassen.
from_address Für ERC-721 transferFrom und safeTransferFrom der aktuelle Inhaber (from) im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung.
approve_all Für ERC-721-setApprovalForAll(operator, approved) das Flag approved als Bool: true, wenn dem Operator die Genehmigung für alle NFTs in der Sammlung erteilt wird, false, wenn sie widerrufen wird.
chain_id Die Ketten-ID der Transaktion. Kann bei Legacy-Transaktionen weggelassen werden. Prüfen Sie dies mit has.
max_fee_atomic Gaslimit × maximale Gebühr pro Gas (oder Gaspreis für Legacy-Transaktionen) in Gwei.

Bei ERC-20-transfer(address, uint256) (0xa9059cbb), deren Selektor für ERC-20 eindeutig ist, wird der Betrag eines Tokens, das von Multi-Party Computation nicht erkannt wird, so skaliert, als hätte das Token 18 Dezimalstellen. Gleichen Sie erkannte Tokens nach contract_address ab und legen Sie keine Betragslimits für nicht erkannte Tokens fest, deren Dezimalstellen nicht 18 sind. ERC-20 transferFrom und approve teilen ihre Selektoren mit ERC-721, sodass sie einen erkannten Vertrag benötigen. Ein Aufruf eines nicht erkannten Vertrags mit einem dieser Selektoren wird mit UNRECOGNIZED_PAYLOAD abgelehnt. Weitere Informationen finden Sie unter ERC-721 Non-Fungible Tokens.

Im Kontext wird nicht angegeben, um welche Art von Ethereum-Transaktion es sich handelt. Beachten Sie daher Folgendes:

  • Vertragsaufrufe, bei denen ETH gesendet werden, sehen wie ETH-Übertragungen aus. Beide haben token_symbol "ETH" und eine amount_token_scaled. Nur ein Vertragsaufruf hat contract_address. Wenn Sie nur ETH-Übertragungen zulassen möchten, fügen Sie !(context has contract_address) hinzu.
  • ERC-20-Genehmigungen sehen aus wie ERC-20-Übertragungen. Ein approve hat dieselben contract_address, amount_token_scaled und secondary_key (den Spender) wie eine Übertragung desselben Betrags an dieselbe Adresse. Eine Richtlinie, die die Übertragung zulässt, lässt auch die Genehmigung zu.

Transaktionen zur Vertragserstellung (mit einer leeren to-Adresse) können nicht decodiert werden und werden mit UNRECOGNIZED_PAYLOAD abgelehnt.

ERC-721-Non-Fungible Tokens

Unter ETHEREUM_TX_V2 decodiert Multi-Party Compute die folgenden ERC-721-Methoden:

  • 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 und ERC-721 verwenden dieselben 4-Byte-Selektoren für transferFrom (0x23b872dd) und approve (0x095ea7b3). Um zu entscheiden, ob das Argument uint256 ein fungibler Betrag oder eine Token-ID ist, sucht Multi-Party Computation die Vertragsadresse to in seiner Registry erkannter Token-Verträge. Bei ERC-721-Aufrufen wird amount_token_scaled weggelassen, token_standard ist "ERC721" und token_id ist ein String zur Basis 10. Ein Aufruf eines nicht erkannten Vertrags mit einem dieser freigegebenen Selektoren wird mit UNRECOGNIZED_PAYLOAD abgelehnt.

EIP-712-typisierte Daten

Bei EIP712_TYPED_DATA_V1-Nutzlasten (UTF-8-JSON-codierte EIP-712-typisierte Daten mit types, primaryType, domain und message) validiert Multi-Party Computation die JSON-Struktur und berechnet den 32-Byte-EIP-712-Signatur-Digest keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)), wobei ++ die Byte-Verkettung ist. Bei der Validierung werden Verschachtelungen mit mehr als 15 Ebenen, zyklische Typen, null-Array-Elemente und domain-Felder, die nicht mit types.EIP712Domain übereinstimmen, abgelehnt. 256-Bit-Ganzzahlen werden ohne Verlust der Gleitkommagenauigkeit beibehalten.

Eine EIP712_TYPED_DATA_V1-Nutzlast projiziert die folgenden Attribute:

Attribut Wert
blockchain Immer "ETH".
schema Immer "EIP712_TYPED_DATA_V1".
contract_address domain.verifyingContract, im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung. Wird weggelassen, wenn die Domain verifyingContract nicht festlegt.
chain_id domain.chainId als Long. Wird weggelassen, wenn die Domain chainId nicht festlegt.
max_fee_atomic Immer 0, da für das Signieren typisierter Daten keine Netzwerkgebühr anfällt.
secondary_key Bei erkannten Nachrichtentypen ist die Gegenpartei: spender für ERC-2612 Permit und Uniswap Permit2 oder to für ERC-3009 TransferWithAuthorization und Safe SafeTx. Für andere Nachrichtentypen domain.verifyingContract.
amount_token_scaled Für erkannte Nachrichtentypen (Permit, Permit2, TransferWithAuthorization und SafeTx) der autorisierte Token- oder ETH-Wert (value oder details.amount) in Einheiten von 10-9. Wird bei anderen Nachrichtentypen weggelassen.
token_symbol "USDC", "USDT", "DAI" oder "WBTC", wenn der Verifizierungsvertrag oder das Permit2-Token (details.token) ein anerkanntes Token im Ethereum-Mainnet ist. Andernfalls wird er weggelassen.
deadline Die Ablaufzeit der Nachricht in Sekunden seit der Unix-Epoche, wenn die Nachricht ein deadline-, sigDeadline- oder validBefore-Feld hat. Andernfalls wird er weggelassen.
eip712 Ein Record mit den typisierten Daten. Weitere Informationen finden Sie in der folgenden Tabelle:

Der eip712-Eintrag enthält die folgenden Felder:

Feld Cedar-Typ Wert
context.eip712.primary_type String Der Name des primaryType, z. B. "Permit", "PermitSingle", "TransferWithAuthorization" oder "SafeTx".
context.eip712.domain Record Die EIP712Domain-Felder, die von der Nutzlast festgelegt werden: name, version, chainId, verifyingContract und salt.
context.eip712.message Record Die message-Felder. 256-Bit-Ganzzahlwerte (uint256 und int256) sind Strings zur Basis 10, sodass Regeln mit genauen Werten ohne 64-Bit-Überlauf übereinstimmen können.

Bitcoin

In der folgenden Tabelle werden die Kontextattribute für BITCOIN_TX_V2-Nutzlasten (BIP 174 PSBT v0) beschrieben:

Attribut Wert
secondary_key Die Adresse der einen Ausgabe, die nicht geändert wird. Bei einer Konsolidierung, bei der jede Ausgabe eine Änderung ist, die Adresse der ersten Ausgabe.
amount_token_scaled Der an secondary_key gesendete Betrag, ohne Wechselgeld (1 Satoshi = 10). 0 für eine Konsolidierung.
token_symbol Immer "BTC".
contract_address Nie vorhanden.
chain_id Nie vorhanden, da eine PSBT nicht angibt, für welches Netzwerk sie bestimmt ist. Adressen werden immer als Mainnet-Adressen formatiert. Daher beginnt eine Testnet-Adresse auch mit bc1, 1 oder 3. Das Adresspräfix gibt den Adresstyp an, nicht das Netzwerk.
max_fee_atomic Die Miner-Gebühr: Gesamteingaben minus Gesamtausgaben (1 Satoshi = 10).

Verwenden Sie unterschiedliche Schlüssel für jedes Netzwerk, um Bitcoin-Netzwerke voneinander zu trennen, z. B. in einem KeyRing für Mainnet und einem anderen für Testnet, und legen Sie Regeln mit principal_keyring oder principal_key fest. Der gleiche Schlüssel kann in beiden Netzwerken verwendet werden. Das funktioniert also nur, wenn Sie einen Mainnet-Schlüssel nie im Testnet verwenden.

Eine Transaktion, die an mehr als eine Adresse gesendet wird, die nicht geändert wird, kann nicht decodiert werden. Eine Transaktion ohne Adresse, an die sie gesendet werden soll, z. B. eine Transaktion, deren einzige Ausgabe, die kein Wechselgeld ist, eine OP_RETURN-Ausgabe ist, kann nicht ausgewertet werden.

Solana

In der folgenden Tabelle werden die Kontextattribute für SOLANA_TX_V1-Nutzlasten (nicht signierte Legacy- oder v0-Solana-Nachrichten) beschrieben:

Attribut Wert
secondary_key Bei SOL-Übertragungen die Ziel-Wallet. Bei Tokenübertragungen das Ziel-Tokenkonto, nicht die Wallet, zu der es gehört. In Base58.
amount_token_scaled Der Betrag. Für SOL die Anzahl der Lamports (1 Lamport = 1). Für Tokens der Rohbetrag, skaliert mit den Dezimalstellen, die die TransferChecked-Anweisung enthält.
token_symbol "SOL" für SOL-Übertragungen. Für Tokens: "USDC", "USDT" oder "PYUSD"; wird für andere Prägestätten weggelassen.
contract_address Für Tokenübertragungen die Mint-Adresse in Base58. Wird bei SOL-Übertragungen weggelassen.
chain_id Nie vorhanden. In Solana-Nachrichten wird kein Cluster genannt.
max_fee_atomic Der Höchstbetrag, der für die gesamte Transaktion in Lamports gezahlt werden kann: 5.000 für jede erforderliche Signatur plus die Prioritätsgebühr, ⌈Limit für Recheneinheiten × Preis pro Recheneinheit in Mikrolamports ÷ 106⌉, wenn für die Transaktion ein Preis pro Recheneinheit festgelegt ist.

Eine Solana-Transaktion kann mehrere Anweisungen enthalten:

  • Übertragungsanweisungen: Systemprogramm Transfer (SOL) und SPL-Token oder Token-2022 TransferChecked. Die ungeprüfte Transfer-Anweisung und Tokens mit mehr als 9 Dezimalstellen können nicht decodiert werden.
  • Andere Anweisungen: ComputeBudget SetComputeUnitLimit und SetComputeUnitPrice, Memo (v1 und v2), Associated Token Account Create und CreateIdempotent sowie System Program AdvanceNonceAccount. Diese Anweisungen erzeugen keinen eigenen Kontext.

Jede Übertragungsanweisung wird separat mit ihrem eigenen Kontext ausgewertet. Die Transaktion ist nur zulässig, wenn jede Übertragung zulässig ist. Wenn eine Übertragung abgelehnt wird, wird die gesamte Transaktion abgelehnt. max_fee_atomic ist die Gebühr für die gesamte Transaktion und ist in jedem Kontext gleich. Addieren Sie sie also nicht über Übertragungen hinweg.

Wenn in der Transaktion ein Preis für Recheneinheiten ohne Limit für Recheneinheiten festgelegt wird, wird für die Gebühr das Solana-Standardlimit von 200.000 Recheneinheiten für jede Anweisung außer ComputeBudget-Anweisungen verwendet, bis zu 1.400.000.

Die Signierer der Transaktion müssen mit den Konten übereinstimmen, die für jede Anweisung signiert werden müssen, und die Quell- und Zielkonten müssen beschreibbar sein. v0-Nachrichten, die Adress-Suchtabellen verwenden, können nicht decodiert werden. Übergeben Sie die nicht signierten Nachrichtenbytes, nicht einen signierten Transaktions-Envelope, in Transaction.payload und Transaction.rawMessage.

Die erkannten Mints sind die Solana-Mainnet-Mints. Im Devnet oder Testnet hat eine Tokenübertragung keine token_symbol. Prüfen Sie stattdessen contract_address.

Eine Create-Anweisung für ein verknüpftes Token-Konto finanziert die mietfreie Reserve des neuen Kontos in SOL. Dieser Betrag ist nicht in amount_token_scaled.

Beispielregeln

Die folgenden Beispiele sind permit- und forbid-Richtlinien, die Sie anpassen können. In jedem Beispiel wird jedes optionale Attribut mit has geprüft, bevor es gelesen wird.

Kauflimit für einen Schlüsselbund mit Nutzlast und Metadaten

Erlaube buy_transaction-Übertragungen von bis zu 500.000 USDC im Ethereum-Mainnet von einem beliebigen Schlüssel im institutional-treasury-Schlüsselbund, wenn der Initiator die Transaktion mit "equities-desk" kennzeichnet, eine Gültigkeit von höchstens 300 Sekunden festlegt und einen Wert von höchstens 500.000 $ angibt:

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"
};

Bei der Multi-Party Computation wird fiat_amount nicht mit der Nutzlast abgeglichen. Weitere Informationen finden Sie unter Kontextattribute.

Ausgabenlimit für einen Schlüssel

ETH-Übertragungen von bis zu 1 ETH von einem Schlüssel im Ethereum-Mainnet zulassen. !(context has contract_address) schließt Vertragsaufrufe aus, die ETH senden:

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
};

Zulassungsliste für Stablecoins auf Ethereum

Übertragungen von bis zu 5.000 USDC an eine Adresse und Genehmigungen (Zulassungen) von bis zu 5.000 USDC für diese Adresse zulassen. Die Richtlinie prüft contract_address und nicht token_symbol. Ein Token aus einem anderen Vertrag, der dasselbe Symbol verwendet, stimmt also nicht überein:

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 ist für diese Transaktion "USDC".

ERC-721-Übertragung und Operator-Genehmigungsschutz

Übertragung eines tokenisierten Schatzbriefs (token_id == "1042") von einem genehmigten ERC-721-Vertrag an eine Abrechnungsadresse zulassen und die Erteilung von sammlungsweiten Operatorgenehmigungen (setApprovalForAll mit approve_all == true) verbieten.

Richtlinie A erlaubt die Übertragung eines 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"
};

Richtlinie B verbietet sammlungsweite Operatorgenehmigungen:

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

EIP-712-Limit für gaslose USDC-Genehmigungen

Genehmigung der Signierung eines Off-Chain-ERC-2612-Permit für bis zu 25.000 USDC im Ethereum-Mainnet für einen genehmigten Settlement-Router, wenn die Genehmigung vor einem bestimmten Zeitpunkt abläuft:

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
};

Bitcoin-Ausgabenlimit und Gebührenobergrenze

Übertragungen von bis zu 0,0025 BTC mit einer Miner-Gebühr von bis zu 10.000 Satoshis von Schlüsseln in einem Schlüsselbund zulassen, den Sie nur im Bitcoin-Mainnet verwenden:

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
};

SOL-Übertragung und Limit für Prioritätsgebühr

SOL-Übertragungen von bis zu 1,5 SOL zulassen, wenn die Gesamtgebühr, einschließlich etwaiger Prioritätsgebühren, maximal 50.000 Lamports (0,00005 SOL) beträgt:

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
};

SPL-Token- oder Token-2022-Übertragung auf Solana

Übertragungen von bis zu 250 USDC auf ein Tokenkonto zulassen. Dieselbe Regel gilt für die Programme „SPL Token“ und „Token-2022“, da im Kontext nicht angegeben ist, welches Programm für die Übertragung verwendet wird:

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 ist das Tokenkonto des Empfängers für diese Prägung. Wenn Sie eine Empfänger-Wallet zulassen möchten, listen Sie das Tokenkonto für jede zulässige Mint auf. In einer Transaktion mit mehreren Übertragungen muss diese Regel mit jeder Übertragung übereinstimmen.

Nicht erkannter Asset-Block

Lehnen Sie alle Übertragungen ab, deren Asset von Multi-Party Computation nicht erkannt wird. Diese forbid-Richtlinie verwendet nur has, sodass die Auswertung nicht fehlschlagen kann:

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

Gebührenobergrenze für eine Blockchain

max_fee_atomic ist immer vorhanden, sodass die forbid-Richtlinie immer ausgewertet werden kann. Da die Skala 10-9 der jeweiligen nativen Coin beträgt, entspricht dieselbe Zahl auf jeder Blockchain einem anderen Wert. Beschränken Sie die Richtlinie auf eine Blockchain:

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

Dadurch werden Ethereum-Transaktionen abgelehnt, bei denen mehr als 0,01 ETH an Gebühren anfallen können.

KeyRings

Ein KeyRing ist ein statischer Container, der MPC-Schlüssel gruppiert, z. B. "institutional-treasury" oder "btc-cold-storage". Jeder Schlüssel wird in einem einzelnen Schlüsselbund erstellt und bleibt dauerhaft in diesem Schlüsselbund.

Schlüsselbunde sind auf drei Arten in Richtlinien eingebunden:

  • KeyRing KeyPolicy (Signatur-Quorum). Wenn Sie einen KeyRing erstellen, legen Sie seine unveränderliche KeyPolicy fest. Diese definiert den Schwellenwertbaum von Teams und Nutzern, die Schlüsselfreigaben haben und zustimmen müssen, bevor ein Schlüssel im KeyRing signieren kann. Transaktionsrichtlinien funktionieren zusammen mit dem KeyPolicy: Die Transaktionsrichtlinie wertet die Geschäftsregeln für die Nutzlast (PERMIT oder DENY) aus, während der KeyPolicy des KeyRings bestimmt, welche Schlüsselfreigaben die Signaturzeremonie autorisieren müssen.
  • Transaktionsrichtlinien nach Signatur-Schlüsselbund (context.principal_keyring) eingrenzen: Der Kontext jeder Transaktion enthält context.principal_keyring, festgelegt auf die ID des Schlüsselbunds, der den Signaturschlüssel enthält, und context.principal_key, festgelegt auf die ID des Signaturschlüssels. Eine Regel mit context.principal_keyring == "institutional-treasury" gilt für jeden Schlüssel im Schlüsselbund, einschließlich der Schlüssel, die später in diesem Schlüsselbund erstellt werden, ohne dass eine neue Richtlinie erstellt oder genehmigt werden muss:

    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
    };
    
  • Zulassungsliste für Ziel-KeyRings (in einer KeyList). Sie können einen KeyRing auch als Eintrag in eine KeyList aufnehmen, sodass Übertragungen an die Blockchain-Adresse eines beliebigen aktiven Schlüssels in diesem KeyRing, z. B. interne Sweeps zwischen Hot- und Cold-KeyRings, automatisch zulässig sind, wenn neue Schlüssel erstellt werden. Ein Beispiel finden Sie unter Zulassungs- und Sperrliste für KeyList.

Zulassungs- und Sperrliste für KeyList

Übertragungen von bis zu 1 ETH nur an Adressen in der KeyList trusted-destinations zulassen. context.key_lists["trusted-destinations"] ist die Gruppe von Adressen, auf die die KeyList bei der createTime der Transaktion erweitert wird. Wenn Sie also einen Eintrag hinzufügen oder entfernen, ändert sich das, was diese Regel zulässt, ohne dass eine neue Richtlinie erforderlich ist:

// 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
};

Lehnen Sie alle Transaktionen an eine Adresse in der KeyList blocked-addresses auf jeder Blockchain ab. key_lists und secondary_key sind immer vorhanden und CreateTransactionPolicy prüft, ob die KeyList vorhanden ist. Daher kann die Auswertung dieser forbid-Richtlinie nicht fehlschlagen:

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

Schreiben Sie die KeyList-ID in Klammersyntax, context.key_lists["..."], und nicht in Punktsyntax. Die Punktsyntax kann nicht für IDs geparst werden, die einen Bindestrich enthalten oder mit einer Ziffer beginnen. Einträge werden als Strings verglichen. Fügen Sie daher manuelle Einträge im Adressformat hinzu, das in der Tabelle für die jeweilige Blockchain beschrieben ist. Weitere Informationen finden Sie unter KeyLists im Cedar-Kontext.