本頁面說明交易政策可檢查的屬性,並提供以太坊 (ETHEREUM_TX_V2 和 EIP712_TYPED_DATA_V1)、比特幣 (BITCOIN_TX_V2) 和 Solana (SOLANA_TX_V1) 交易的規則範例。
如要瞭解政策如何合併、哪些政策會強制執行,以及交易遭拒的原因,請參閱「交易政策評估」。
規則結構
交易政策是單一 Cedar
permit 或 forbid 陳述式,涵蓋主體、動作、資源和情境:
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
};
請注意以下幾點:
- 屬性位於內容的最上層。請寫
context.amount_token_scaled,而非context.transaction.spend_amount_scaled,如v1alpha1。 - 部分屬性為選填。如果政策包含選用屬性,但該屬性不在情境中,政策就無法評估,而無法評估的政策不會比對成功。讀取前,請先使用
has檢查是否有選用屬性,或在forbid規則中使用unless { context has ... }。詳情請參閱情境 6 和情境 8。 - Cedar 字串會區分大小寫。請按照各連鎖店表格說明的格式,比較地址。
如需主體,請參閱「Cedar 要求」。如要瞭解 CreateTransaction 接受的動作 (buy_transaction、sell_transaction 和 internal_transfer_transaction),請參閱「動作和資源」。
情境屬性
每筆交易的背景資訊都包含從其酬載解碼的屬性、簽署金鑰及其 KeyRing 的 ID,以及發起者設定的中繼資料屬性 (fiat_amount、validity、principal_value1 和 principal_value2)。
每個區塊鏈的酬載屬性都相同。下表說明所有情境屬性,而 Ethereum、Bitcoin 和 Solana 的表格則說明多方運算如何為該區塊鏈填入各個屬性:
| 屬性 | Cedar 類型 | 一律顯示? | 值 |
|---|---|---|---|
schema |
String |
是 | 酬載格式:"ETHEREUM_TX_V2"、"BITCOIN_TX_V2"、"SOLANA_TX_V1" 或 "EIP712_TYPED_DATA_V1"。詳情請參閱「結構定義名稱」。 |
blockchain |
String |
是 | "ETH"、"BTC" 或 "SOL"。 |
principal_keyring |
String |
是 | 存放簽署金鑰的金鑰環 ID,例如 "treasury"。 |
principal_key |
String |
是 | 簽署金鑰的 ID,例如 "hot-wallet-1"。 |
secondary_key |
String |
是 | 從酬載解碼的目的地位址、代幣或 NFT 收件者、核准的支出者或操作者,或 EIP-712 交易對象。 |
amount_token_scaled |
Long |
否 | 轉移或核准的可替代金額,以資產的 10-9 為單位。如果沒有轉移可替代金額,例如 ERC-721 作業或未傳送 ETH 的合約呼叫,則會省略。詳情請參閱「金額」一節。 |
token_symbol |
String |
否 | 資產的代號,例如 "ETH"、"BTC"、"SOL" 或 "USDC"。如果資產不是多方運算可辨識的資產,以及用於 ERC-721 作業,則會省略。 |
contract_address |
String |
否 | ERC-20 或 ERC-721 代幣合約或呼叫合約 (Ethereum)、驗證合約 (EIP-712) 或鑄造 (Solana)。原生轉移作業會省略這項資訊。 |
token_standard |
String |
否 | ERC-721 轉移和核准 (ETHEREUM_TX_V2) 的 "ERC721"。原生轉移和同質代幣作業會省略。 |
token_id |
String |
否 | 256 位元 ERC-721 tokenId,以 10 進位字串 (ETHEREUM_TX_V2) 表示。如果是 setApprovalForAll 和非 ERC-721 交易,則會省略。 |
from_address |
String |
否 | ERC-721 transferFrom 和 safeTransferFrom 呼叫中的目前擁有者 (from),採用大小寫混合的 EIP-55 核對和格式。 |
approve_all |
Bool |
否 | ERC-721 setApprovalForAll(operator, approved) 呼叫中的 approved 標記:授予操作員核准時為 true,撤銷時為 false。 |
deadline |
Long |
否 | EIP712_TYPED_DATA_V1 訊息的到期時間,從 Unix 紀元起算,以秒為單位,取自 deadline、sigDeadline 或 validBefore 欄位。 |
eip712 |
Record |
否 | 結構化 EIP-712 酬載:primary_type、domain 和 message,256 位元整數為 10 進位字串。僅限EIP712_TYPED_DATA_V1。 |
chain_id |
Long |
否 | EVM 鏈 ID,例如以太坊主網的 1 或 Sepolia 的 11155111。僅限 Ethereum 和 EIP-712。 |
max_fee_atomic |
Long |
是 | 交易可支付的網路費用上限,單位為區塊鏈原生代幣的 10-9。0,費用只要 EIP712_TYPED_DATA_V1。 |
payload |
String |
是 | 酬載的十六進位編碼摘要,以小寫表示。 |
time_stamp |
Long |
是 | 交易的 createTime,以秒為單位 (自 Unix 紀元起算)。 |
key_lists |
Record/Set<String> |
是 | 這項記錄會將執行個體中的每個 KeyList ID,對應至該 KeyList 中區塊鏈位址的 Set<String>,並在 createTime 解析。如果執行個體沒有 KeyList,則會顯示空白記錄。使用括號語法讀取 KeyList,例如 context.key_lists["trusted-destinations"]。詳情請參閱「Cedar 內容中的 KeyList」。 |
principal_keyring 和 principal_key 是 ID,而非完整資源名稱。金鑰 ID 僅在所屬 KeyRing 內是唯一的。勾選 principal_keyring,將規則套用至金鑰環中的每個金鑰,或同時勾選這兩個屬性,指定一個金鑰:
context.principal_keyring == "treasury" && context.principal_key == "hot-wallet-1"
如果剖析器無法解碼 Transaction.schema 的酬載,或無法將酬載投影至情境,系統就不會評估任何政策,並會拒絕交易,同時傳回 UNRECOGNIZED_PAYLOAD。詳情請參閱「拒絕原因」。
結構定義名稱
schema 屬性是 v1beta API 中 PayloadSchema 值的名稱:"ETHEREUM_TX_V2"、"BITCOIN_TX_V2"、"SOLANA_TX_V1" 或 "EIP712_TYPED_DATA_V1"。v1alpha1 規則使用的小寫名稱 (例如 "ethereum.transaction.v2") 絕不會與 v1beta 中的名稱相符。
如果規則未檢查 schema 或 blockchain,則適用於所有區塊鏈。如要將規則限制在一個區塊鏈,請勾選 schema。
金額
amount_token_scaled 和 max_fee_atomic 對每項資產使用相同的比例:1 單位是資產的 10-9,因此任何資產的 1.0 都是 1000000000。如要取得規則的值,請將金額乘以 1,000,000,000 (109)。下表列出一些範例:
| 金額 | amount_token_scaled |
|---|---|
| 0.1 ETH | 100000000 |
| 1.0 ETH、1.0 BTC、1.0 SOL 或 1.0 USDC | 1000000000 |
| 0.0025 BTC (250,000 satoshis) | 2500000 |
| 1.5 SOL (1,500,000,000 lamports) | 1500000000 |
| 5,000 USDC | 5000000000000 |
如果資產的小數位數超過 9 位 (例如 ETH),則會捨去小於 10-9 的金額部分。規則無法檢查。
Ethereum
下表說明 ETHEREUM_TX_V2 酬載 (RLP 編碼的舊版和 EIP-2718 交易,包括 EIP-1559) 的內容屬性:
| 屬性 | 值 |
|---|---|
secondary_key |
如果是 ETH 轉帳和合約呼叫,則為交易的 to 位址。如果是 ERC-20 transfer 和 transferFrom,以及 ERC-721 transferFrom 和 safeTransferFrom,則為代幣或 NFT 接收者。如果是 ERC-20 和 ERC-721 approve,則為已核准的支出者。如果是 ERC-721 setApprovalForAll,則為操作者。採用大小寫混合的 EIP-55 核對和格式。 |
amount_token_scaled |
ETH 轉帳、ERC-20 轉帳和核准的金額。如果是合約呼叫,則為隨呼叫傳送的 ETH;如未傳送 ETH,則會省略。ERC-721 轉移和核准一律會省略,因此同質化支出上限與 NFT 詞元 ID 不符。 |
token_symbol |
"ETH":用於 ETH 轉帳,以及傳送 ETH 的合約呼叫。如果是 Ethereum 主網、"USDC"、"USDT"、"DAI" 或 "WBTC" 上公認的 ERC-20 代幣,則會顯示這個欄位;如果是其他代幣和 ERC-721 作業,則會省略這個欄位。 |
contract_address |
如果是 ERC-20 和 ERC-721 轉移和核准,則為代幣或 NFT 合約。如果是合約呼叫,則為呼叫的合約。採用大小寫混合的 EIP-55 核對和格式。ETH 轉帳時會省略。 |
token_standard |
"ERC721":用於 ERC-721 轉移和核准。ETH 轉帳、ERC-20 作業和其他合約呼叫會省略這項資訊。 |
token_id |
對於 ERC-721 transferFrom、safeTransferFrom 和 approve,256 位元 tokenId 會以 10 進位 String 表示,因此 NFT ID 絕不會溢位 Cedar 的 64 位元 Long。由於這是 String,請比較它與 == 或 in [...] 是否相等;< 和 > 比較的是字串,而非數字。setApprovalForAll 和非 ERC-721 交易會省略。 |
from_address |
如果是 ERC-721 transferFrom 和 safeTransferFrom,則為目前擁有者 (from),採用大小寫混合的 EIP-55 核對和格式。 |
approve_all |
如果是 ERC-721 setApprovalForAll(operator, approved),approved 標記為 Bool:true 表示授予操作員對集合中每個 NFT 的核准權限,false 表示撤銷權限。 |
chain_id |
交易的鏈結 ID。在舊版交易中可以省略,因此請使用 has 進行檢查。 |
max_fee_atomic |
Gas 上限 × 每單位 Gas 最高費用 (或舊版交易的 Gas 價格),以 gwei 為單位。 |
如果是 ERC-20 transfer(address, uint256) (0xa9059cbb),其選取器是 ERC-20 專屬,多方運算無法辨識的代幣會調整金額,就像代幣有 18 個小數位數一樣。依 contract_address 比對已辨識的代幣,且不對小數點位數不是 18 的未辨識代幣設定金額限制。ERC-20 transferFrom 和 approve 與 ERC-721 共用選取器,因此需要可辨識的合約;如果使用其中一個選取器呼叫無法辨識的合約,系統會拒絕並傳回 UNRECOGNIZED_PAYLOAD。詳情請參閱「ERC-721 非同質化代幣」。
上下文並未說明這是哪種以太坊交易,因此請注意下列事項:
- 傳送 ETH 的合約呼叫看起來像 ETH 轉帳。兩者都有
token_symbol"ETH"和amount_token_scaled。只有合約呼叫有contract_address。如要僅允許 ETH 轉帳,請新增!(context has contract_address)。 - ERC-20 核准看起來像 ERC-20 轉帳。
approve的contract_address、amount_token_scaled和secondary_key(支出者) 與轉移相同金額至相同地址時相同。允許轉移的政策也允許核准。
合約建立交易 (to 位址空白) 無法解碼,並會遭到 UNRECOGNIZED_PAYLOAD 拒絕。
ERC-721 非同質化代幣
在 ETHEREUM_TX_V2 下,Multi-party Compute 會解碼下列 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 和 ERC-721 的 transferFrom (0x23b872dd) 和 approve (0x095ea7b3) 共用相同的 4 位元組選取器。為判斷 uint256 引數是可替代金額還是詞元 ID,多方運算會在已辨識代幣合約的登錄檔中查詢 to 合約地址。如果是 ERC-721 呼叫,則會省略 amount_token_scaled,token_standard 為 "ERC721",token_id 則為 10 進位 String。如果使用其中一個共用選取器呼叫無法辨識的合約,系統會拒絕並傳回 UNRECOGNIZED_PAYLOAD。
EIP-712 類型資料
對於 EIP712_TYPED_DATA_V1 酬載 (採用 UTF-8 JSON 編碼的 EIP-712 類型資料,包含 types、primaryType、domain 和 message),多方運算會驗證 JSON 結構,並計算 32 位元組 EIP-712 簽署摘要 keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)),其中 ++ 是位元組串連。驗證作業會拒絕超過 15 層的巢狀結構、循環類型、null 陣列元素,以及與 types.EIP712Domain 不符的 domain 欄位,並保留 256 位元整數,不會損失浮點精確度。
EIP712_TYPED_DATA_V1 酬載會投影下列屬性:
| 屬性 | 值 |
|---|---|
blockchain |
一律"ETH"。 |
schema |
一律"EIP712_TYPED_DATA_V1"。 |
contract_address |
domain.verifyingContract,採用大小寫混合的 EIP-55 核對和格式。如果網域未設定 verifyingContract,則會省略。 |
chain_id |
以 Long 格式指定的 domain.chainId。如果網域未設定 chainId,則會省略。 |
max_fee_atomic |
一律為 0,因為簽署類型資料不需支付網路費用。 |
secondary_key |
如果是可辨識的訊息類型,則為交易對手:ERC-2612 Permit 和 Uniswap Permit2 的 spender,或 ERC-3009 TransferWithAuthorization 和 Safe SafeTx 的 to。如需其他訊息類型的相關資訊,請參閱domain.verifyingContract。 |
amount_token_scaled |
如果是可辨識的訊息類型 (Permit、Permit2、TransferWithAuthorization 和 SafeTx),則為授權代幣或 ETH 值 (value 或 details.amount),單位為 10-9。其他訊息類型則會省略。 |
token_symbol |
"USDC"、"USDT"、"DAI" 或 "WBTC",前提是驗證合約或 Permit2 代幣 (details.token) 是以太坊主網上公認的代幣。否則會省略。 |
deadline |
訊息的到期時間,以 Unix 紀元時間起算的秒數表示,訊息有 deadline、sigDeadline 或 validBefore 欄位時適用。否則會省略。 |
eip712 |
包含輸入資料的 Record。詳情請參閱下表。 |
eip712 記錄包含下列欄位:
| 欄位 | Cedar 類型 | 值 |
|---|---|---|
context.eip712.primary_type |
String |
primaryType 名稱,例如 "Permit"、"PermitSingle"、"TransferWithAuthorization" 或 "SafeTx"。 |
context.eip712.domain |
Record |
酬載設定的 EIP712Domain 欄位:name、version、chainId、verifyingContract 和 salt。 |
context.eip712.message |
Record |
message 欄位。256 位元整數值 (uint256 和 int256) 是 10 進位 String,因此規則可以比對確切值,不會發生 64 位元溢位。 |
比特幣
下表說明 BITCOIN_TX_V2 酬載 (BIP 174 PSBT v0) 的情境屬性:
| 屬性 | 值 |
|---|---|
secondary_key |
未變更的輸出內容地址。如果是合併交易 (每個輸出內容都是找零),則為第一個輸出內容的地址。 |
amount_token_scaled |
傳送至 secondary_key 的金額,不含找零 (1 聰 = 10)。0 用於合併。 |
token_symbol |
一律"BTC"。 |
contract_address |
絕不出現。 |
chain_id |
一律不會顯示,因為 PSBT 不會說明適用的網路。地址一律採用主網地址格式,因此測試網地址也會以 bc1、1 或 3 開頭。位址前置字串會顯示位址類型,而非網路。 |
max_fee_atomic |
礦工手續費:總輸入減去總輸出 (1 聰 = 10)。 |
如要區分比特幣網路,請為每個網路使用不同的金鑰,例如在主網和測試網分別使用不同的 KeyRing,並使用 principal_keyring 或 principal_key 將規則範圍限定在這些金鑰。同一個金鑰可以在兩個網路上簽署,因此只有在 Testnet 上不使用 Mainnet 金鑰時,這個方法才有效。
如果交易傳送至多個非找零地址,則無法解碼。如果交易沒有傳送地址 (例如唯一非找零的輸出內容是 OP_RETURN 輸出內容),就無法評估。
Solana
下表說明 SOLANA_TX_V1 酬載 (未簽署的舊版或 v0 Solana 訊息) 的情境屬性:
| 屬性 | 值 |
|---|---|
secondary_key |
SOL 轉帳的目的地錢包。如果是代幣轉移,則為目標代幣帳戶,而非擁有該帳戶的錢包。採用 base58 格式。 |
amount_token_scaled |
金額。如果是 SOL,則為 lamport 數量 (1 lamport = 1)。如果是代幣,則為原始金額乘以 TransferChecked 指令攜帶的小數位數。 |
token_symbol |
"SOL"用於 SOL 轉帳。代幣:"USDC"、"USDT" 或 "PYUSD";其他鑄幣則省略。 |
contract_address |
如果是代幣轉移,則為鑄造地址 (base58)。SOL 轉帳時會省略。 |
chain_id |
絕不出現。Solana 訊息不會指定叢集。 |
max_fee_atomic |
整筆交易最多可支付的 lamport 數量:每個必要簽章 5,000 個,加上優先費用 ⌈運算單元限制 × 運算單元價格 (以微 lamport 為單位) ÷ 106⌉ (如果交易設定了運算單元價格)。 |
Solana 交易可包含多個指令:
- 轉移指令:系統程式
Transfer(SOL),以及 SPL Token 或 Token-2022TransferChecked。未經檢查的Transfer指令,以及小數點後超過 9 位的代幣,都無法解碼。 - 其他指令:ComputeBudget
SetComputeUnitLimit和SetComputeUnitPrice、Memo (v1 和 v2)、Associated Token AccountCreate和CreateIdempotent,以及 System ProgramAdvanceNonceAccount。這些指令不會產生自己的情境。
每項轉移指示都會根據其背景資訊個別評估。只有在每筆轉移都獲得許可時,交易才會獲得許可;如果任何轉移遭到拒絕,整筆交易就會遭到拒絕。max_fee_atomic 是整筆交易的費用,在所有情況下都相同,因此請勿在轉帳時累加。
如果交易設定了運算單元價格,但未設定運算單元上限,則手續費會採用 Solana 預設上限,即 ComputeBudget 指令以外的每個指令 200,000 個運算單元,最多 1,400,000 個。
交易的簽署者必須與每項指令需要簽署的帳戶相符,且來源和目標帳戶必須可寫入。使用位址對照表的 v0 訊息無法解碼。在 Transaction.payload 和 Transaction.rawMessage 中,傳遞未簽署的訊息位元組,而非已簽署的交易信封。
系統認可的鑄幣是 Solana 主網鑄幣。在 Devnet 或 Testnet 上,代幣轉移沒有 token_symbol,因此請改為查看 contract_address。
關聯代幣帳戶 Create 指令會以 SOL 形式,為新帳戶的免租金儲備金提供資金。該金額並非以amount_token_scaled計價。
規則範例
以下是 permit 和 forbid 政策範例,您可以視需要調整。每個範例都會先使用 has 檢查每個選用屬性,然後再讀取。
使用酬載和中繼資料的金鑰環購買限制
當發起人將交易標示為 "equities-desk"、設定有效期限不超過 300 秒,並聲明價值不超過 $500,000 美元時,允許 buy_transaction 透過 institutional-treasury KeyRing 中的任何金鑰,在 Ethereum Mainnet 上轉移最多 500,000 USDC:
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"
};
多方運算不會根據酬載檢查 fiat_amount。詳情請參閱「情境屬性」。
單一金鑰的花費上限
允許從以太坊主網上的單一金鑰轉移最多 1 ETH。!(context has contract_address) 會排除傳送 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
};
以太坊上的穩定幣許可清單
允許轉移最多 5,000 USDC 到一個地址,並核准 (配額) 該地址最多 5,000 USDC。這項政策會檢查 contract_address,而非 token_symbol,因此使用相同符號的其他合約代幣不會相符:
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"。
ERC-721 轉移和操作員核准防護
允許將一個代幣化國庫券 (token_id == "1042") 從核准的 ERC-721 合約轉移至結算地址,並禁止授予整個集合的運算子核准 (setApprovalForAll 搭配 approve_all == true)。
政策 A 允許轉移一個 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"
};
政策 B 禁止核准整個集合的操作員:
forbid (principal, action, resource)
when {
context.schema == "ETHEREUM_TX_V2" &&
context has approve_all && context.approve_all == true
};
EIP-712 免 Gas 費 USDC 授權上限
允許在以太坊主網上簽署鏈下 ERC-2612 Permit,最多可為核准的結算路由器提供 25,000 USDC,且許可在指定時間前到期:
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
};
比特幣支出上限和手續費上限
允許從您僅在比特幣主網上使用的 KeyRing 金鑰轉移最多 0.0025 BTC,礦工手續費最多 10,000 satoshis:
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 轉帳和優先手續費上限
當總費用 (包括任何優先費用) 最多為 50,000 lamports (0.00005 SOL) 時,允許轉移最多 1.5 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
};
在 Solana 轉移 SPL 代幣或 Token-2022
允許將最多 250 USDC 轉移至一個代幣帳戶。由於上下文並未說明轉移作業使用哪個程式,因此同一規則會比對 SPL Token 和 Token-2022 程式:
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 是收款人用於這次鑄造的代幣帳戶。如要允許收款錢包,請為每個允許的鑄造列出其代幣帳戶。在包含多筆轉移的交易中,這項規則必須與每筆轉移相符。
無法辨識的資產區塊
拒絕多方運算無法辨識資產的任何轉移。這項 forbid 政策僅使用 has,因此評估不會失敗:
forbid (principal, action, resource)
when { context has amount_token_scaled }
unless { context has token_symbol };
區塊鏈手續費上限
max_fee_atomic 一律存在,因此這項 forbid 政策不會評估失敗。由於每個原生代幣的規模為 10-9,因此在每個區塊鏈上,相同的數字代表不同的值。將政策範圍限定為一個區塊鏈:
forbid (principal, action, resource)
when { context.blockchain == "ETH" && context.max_fee_atomic > 10000000 };
這會拒絕手續費超過 0.01 ETH 的以太坊交易。
金鑰環
KeyRing 是靜態容器,可將 MPC 金鑰分組,例如 "institutional-treasury" 或 "btc-cold-storage"。每組金鑰都是在單一 KeyRing 中建立,並永久保留在該 KeyRing 中。
金鑰環會透過三種方式參與政策:
- KeyRing
KeyPolicy(簽署法定人數)。建立 KeyRing 時,您會設定其不可變更的 KeyPolicy,定義持有金鑰共用權限的團隊和使用者門檻樹狀結構,且必須先獲得核准,KeyRing 中的任何金鑰才能簽署。交易政策會與KeyPolicy搭配運作:交易政策會評估酬載 (PERMIT或DENY) 的業務規則,而 KeyRing 的KeyPolicy則會控管哪些金鑰共用必須授權簽署儀式。 依簽署 KeyRing (
context.principal_keyring) 劃分交易政策範圍。每筆交易的背景資訊都包含context.principal_keyring(設為保存簽署金鑰的 KeyRing ID) 和context.principal_key(設為簽署金鑰的 ID)。含有context.principal_keyring == "institutional-treasury"的規則會套用至金鑰環中的所有金鑰,包括日後在該金鑰環中建立的金鑰,不需建立或核准新政策: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 };目的地 KeyRing 許可清單 (位於 KeyList)。您也可以將 KeyRing 新增為 KeyList 中的項目,這樣一來,當系統建立新金鑰時,就會自動允許轉移至該 KeyRing 中任何有效金鑰的區塊鏈位址,例如熱 KeyRing 和冷 KeyRing 之間的內部掃描。如需範例,請參閱「KeyList 許可清單和封鎖清單」。
KeyList 許可清單和封鎖清單
僅允許將最多 1 ETH 轉移至 trusted-destinations KeyList 中的地址。context.key_lists["trusted-destinations"] 是 KeyList 在交易 createTime 展開的位址集,因此新增或移除項目會變更這項規則允許的內容,而不需要新的政策:
// 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
};
拒絕所有區塊鏈上,向 blocked-addresses KeyList 中地址進行的交易。key_lists 和 secondary_key 一律存在,且 CreateTransactionPolicy 會驗證 KeyList 是否存在,因此這項 forbid 政策不會無法評估:
// Assuming you created a KeyList with ID "blocked-addresses":
forbid (principal, action, resource)
when { context.key_lists["blocked-addresses"].contains(context.secondary_key) };
請使用括號語法 context.key_lists["..."] 寫入 KeyList ID,而非點語法。如果 ID 含有連字號或開頭為數字,點語法就無法剖析。系統會將項目視為字串進行比較,因此請按照各區塊鏈資料表說明的地址格式,手動新增項目。詳情請參閱「Cedar 內容中的 KeyList」。