Menulis aturan kebijakan transaksi

Halaman ini menjelaskan atribut yang dapat diperiksa oleh kebijakan transaksi, dan menunjukkan contoh aturan untuk transaksi Ethereum (ETHEREUM_TX_V2 dan EIP712_TYPED_DATA_V1), Bitcoin (BITCOIN_TX_V2), dan Solana (SOLANA_TX_V1).

Untuk mempelajari cara kebijakan digabungkan, kebijakan mana yang diterapkan, dan alasan transaksi ditolak, lihat Evaluasi kebijakan transaksi.

Struktur aturan

Kebijakan transaksi adalah satu pernyataan Cedar permit atau forbid atas akun utama, tindakan, resource, dan konteks:

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

Ingat hal berikut:

  • Atribut berada di tingkat teratas konteks. Tulis context.amount_token_scaled, bukan context.transaction.spend_amount_scaled seperti dalam v1alpha1.
  • Beberapa atribut bersifat opsional. Atribut opsional yang tidak ada dalam konteks akan membuat kebijakan gagal dievaluasi, dan kebijakan yang gagal dievaluasi tidak akan cocok. Periksa atribut opsional dengan has sebelum Anda membacanya, atau dengan unless { context has ... } dalam aturan forbid. Untuk mengetahui informasi selengkapnya, lihat Skenario 6 dan Skenario 8.
  • String Cedar peka huruf besar/kecil. Bandingkan alamat dalam format yang dijelaskan tabel untuk setiap jaringan.

Untuk akun utama, lihat Permintaan Cedar. Untuk tindakan yang diterima CreateTransaction (buy_transaction, sell_transaction, dan internal_transfer_transaction), lihat Tindakan dan resource.

Atribut konteks

Setiap konteks transaksi memiliki atribut yang didekode dari payload-nya, ID kunci penandatanganan dan KeyRing-nya, serta atribut metadata (fiat_amount, validity, principal_value1, dan principal_value2) yang ditetapkan oleh inisiator.

Atribut payload sama untuk setiap blockchain. Tabel berikut menjelaskan semua atribut konteks, dan tabel untuk Ethereum, Bitcoin, dan Solana menjelaskan cara Multi-party Compute mengisi setiap atribut untuk blockchain tersebut:

Atribut Jenis cedar Selalu ada? Nilai
schema String Ya Format payload: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1", atau "EIP712_TYPED_DATA_V1". Untuk mengetahui informasi selengkapnya, lihat Nama skema.
blockchain String Ya "ETH", "BTC", atau "SOL".
principal_keyring String Ya ID KeyRing yang menyimpan kunci penandatanganan, misalnya "treasury".
principal_key String Ya ID kunci penandatanganan, misalnya "hot-wallet-1".
secondary_key String Ya Alamat tujuan, penerima token atau NFT, pembelanja atau operator yang disetujui, atau pihak lawan EIP-712 yang didekode dari payload.
amount_token_scaled Long Tidak Jumlah sepadan yang ditransfer atau disetujui, dalam unit 10-9 aset. Dihilangkan jika tidak ada jumlah yang dapat dipertukarkan yang ditransfer, misalnya operasi ERC-721 atau panggilan kontrak yang tidak mengirim ETH. Untuk mengetahui informasi selengkapnya, lihat Jumlah.
token_symbol String Tidak Simbol aset, misalnya "ETH", "BTC", "SOL", atau "USDC". Dihilangkan jika aset bukan aset yang dikenali oleh Multi-party Compute, dan untuk operasi ERC-721.
contract_address String Tidak Kontrak token ERC-20 atau ERC-721 atau kontrak yang dipanggil (Ethereum), kontrak verifikasi (EIP-712), atau mint (Solana). Dihilangkan untuk transfer native.
token_standard String Tidak "ERC721" untuk transfer dan persetujuan ERC-721 (ETHEREUM_TX_V2). Dihilangkan untuk transfer native dan operasi token yang dapat dipertukarkan.
token_id String Tidak ERC-721 256-bit tokenId sebagai string base-10 (ETHEREUM_TX_V2). Dihilangkan untuk setApprovalForAll dan untuk transaksi yang bukan ERC-721.
from_address String Tidak Pemilik saat ini (from) dalam panggilan ERC-721 transferFrom dan safeTransferFrom, dalam format checksum EIP-55 dengan huruf besar/kecil campuran.
approve_all Bool Tidak Flag approved dalam panggilan setApprovalForAll(operator, approved) ERC-721: true saat memberikan persetujuan operator, false saat mencabutnya.
deadline Long Tidak Waktu habis masa berlaku pesan EIP712_TYPED_DATA_V1, dalam detik sejak epoch Unix, dari kolom deadline, sigDeadline, atau validBefore.
eip712 Record Tidak Payload EIP-712 terstruktur: primary_type, domain, dan message, dengan bilangan bulat 256-bit sebagai string basis-10. EIP712_TYPED_DATA_V1 saja.
chain_id Long Tidak ID rantai EVM, misalnya 1 untuk Ethereum Mainnet atau 11155111 untuk Sepolia. Hanya Ethereum dan EIP-712.
max_fee_atomic Long Ya Jumlah maksimum yang dapat dibayarkan transaksi dalam biaya jaringan, dalam satuan 10-9 koin native blockchain. 0 untuk EIP712_TYPED_DATA_V1.
payload String Ya Ringkasan payload berenkode hex, dalam huruf kecil.
time_stamp Long Ya createTime transaksi, dalam detik sejak epoch Unix.
key_lists Record dari Set<String> Ya Data yang memetakan setiap ID KeyList dalam instance ke Set<String> alamat blockchain di KeyList tersebut, yang di-resolve di createTime. Data kosong jika instance tidak memiliki KeyList. Baca KeyList dengan sintaksis tanda kurung, misalnya context.key_lists["trusted-destinations"]. Untuk mengetahui informasi selengkapnya, lihat KeyList dalam konteks Cedar.

principal_keyring dan principal_key adalah ID, bukan nama resource lengkap. ID kunci hanya unik dalam KeyRing-nya. Periksa principal_keyring untuk menerapkan aturan ke setiap kunci dalam KeyRing, atau kedua atribut untuk memberi nama satu kunci:

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

Jika payload tidak dapat didekode oleh parser untuk Transaction.schema, atau tidak dapat diproyeksikan ke dalam konteks, tidak ada kebijakan yang dievaluasi dan transaksi akan ditolak dengan UNRECOGNIZED_PAYLOAD. Untuk mengetahui informasi selengkapnya, lihat Alasan penolakan.

Nama skema

Atribut schema adalah nama nilai PayloadSchema di v1beta API: "ETHEREUM_TX_V2", "BITCOIN_TX_V2", "SOLANA_TX_V1", atau "EIP712_TYPED_DATA_V1". Nama huruf kecil yang digunakan aturan v1alpha1, seperti "ethereum.transaction.v2", tidak pernah cocok di v1beta.

Aturan tanpa pemeriksaan schema atau blockchain berlaku untuk setiap blockchain. Untuk membatasi aturan ke satu blockchain, centang schema.

Jumlah

amount_token_scaled dan max_fee_atomic menggunakan skala yang sama untuk setiap aset: 1 unit adalah 10-9 dari aset, sehingga 1,0 dari aset apa pun adalah 1000000000. Untuk mendapatkan nilai aturan, kalikan jumlahnya dengan 1.000.000.000 (109). Tabel berikut menunjukkan beberapa contoh:

Jumlah amount_token_scaled
0,1 ETH 100000000
1,0 ETH, 1,0 BTC, 1,0 SOL, atau 1,0 USDC 1000000000
0,0025 BTC (250.000 satoshi) 2500000
1,5 SOL (1.500.000.000 lamport) 1500000000
5.000 USDC 5000000000000

Untuk aset dengan lebih dari 9 tempat desimal, seperti ETH, bagian jumlah yang lebih kecil dari 10-9 akan dihapus. Aturan tidak dapat memeriksanya.

Ethereum

Tabel berikut menjelaskan atribut konteks untuk payload ETHEREUM_TX_V2 (transaksi lama dan EIP-2718 yang dienkode RLP, termasuk EIP-1559):

Atribut Nilai
secondary_key Untuk transfer ETH dan panggilan kontrak, alamat to transaksi. Untuk ERC-20 transfer dan transferFrom, serta ERC-721 transferFrom dan safeTransferFrom, penerima token atau NFT. Untuk ERC-20 dan ERC-721 approve, pembelanja yang disetujui. Untuk ERC-721 setApprovalForAll, operator. Dalam format checksum EIP-55 huruf besar/kecil.
amount_token_scaled Untuk transfer ETH serta transfer dan persetujuan ERC-20, jumlahnya. Untuk panggilan kontrak, ETH dikirim bersama panggilan; dihilangkan jika tidak ada ETH yang dikirim. Selalu dihilangkan untuk transfer dan persetujuan ERC-721, sehingga batas pembelanjaan yang dapat dipertukarkan tidak cocok dengan ID token NFT.
token_symbol "ETH" untuk transfer ETH, dan untuk panggilan kontrak yang mengirim ETH. Untuk token ERC-20 yang dikenali di Ethereum Mainnet, "USDC", "USDT", "DAI", atau "WBTC"; dihilangkan untuk token lain dan untuk operasi ERC-721.
contract_address Untuk transfer dan persetujuan ERC-20 dan ERC-721, kontrak token atau NFT. Untuk panggilan kontrak, kontrak yang dipanggil. Dalam format checksum EIP-55 huruf besar/kecil. Dihilangkan untuk transfer ETH.
token_standard "ERC721" untuk transfer dan persetujuan ERC-721. Dihilangkan untuk transfer ETH, operasi ERC-20, dan panggilan kontrak lainnya.
token_id Untuk ERC-721 transferFrom, safeTransferFrom, dan approve, tokenId 256-bit sebagai String basis-10, sehingga ID NFT tidak pernah melebihi Long 64-bit Cedar. Karena ini adalah String, bandingkan kesetaraannya dengan == atau in [...]; < dan > membandingkan string, bukan angka. Dihilangkan untuk setApprovalForAll dan untuk transaksi yang bukan ERC-721.
from_address Untuk ERC-721 transferFrom dan safeTransferFrom, pemilik saat ini (from), dalam format checksum EIP-55 huruf besar/kecil.
approve_all Untuk ERC-721 setApprovalForAll(operator, approved), flag approved sebagai Bool: true saat memberikan persetujuan operator atas setiap NFT dalam koleksi, false saat mencabutnya.
chain_id ID rantai dari transaksi. Dapat dihilangkan pada transaksi lama, jadi periksa dengan has.
max_fee_atomic Batas gas × biaya maksimum per gas (atau harga gas untuk transaksi lama), dalam gwei.

Untuk transfer(address, uint256) ERC-20 (0xa9059cbb), yang pemilihnya unik untuk ERC-20, token yang tidak dikenali oleh Multi-party Compute akan diskalakan jumlahnya seolah-olah token tersebut memiliki 18 tempat desimal. Cocokkan token yang dikenali berdasarkan contract_address, dan jangan tetapkan batas jumlah pada token yang tidak dikenali yang desimalnya bukan 18. ERC-20 transferFrom dan approve berbagi pemilihnya dengan ERC-721, sehingga memerlukan kontrak yang dikenali; panggilan ke kontrak yang tidak dikenali dengan salah satu pemilih ini akan ditolak dengan UNRECOGNIZED_PAYLOAD. Untuk mengetahui informasi selengkapnya, lihat Token non-fungible ERC-721.

Konteksnya tidak menyebutkan jenis transaksi Ethereum, jadi perhatikan hal berikut:

  • Panggilan kontrak yang mengirim ETH terlihat seperti transfer ETH. Keduanya memiliki token_symbol "ETH" dan amount_token_scaled. Hanya panggilan kontrak yang memiliki contract_address. Untuk hanya mengizinkan transfer ETH, tambahkan !(context has contract_address).
  • Persetujuan ERC-20 terlihat seperti transfer ERC-20. approve memiliki contract_address, amount_token_scaled, dan secondary_key (pembelanja) yang sama dengan transfer dalam jumlah yang sama ke alamat yang sama. Kebijakan yang mengizinkan transfer juga mengizinkan persetujuan.

Transaksi pembuatan kontrak (dengan alamat to kosong) tidak dapat didekode dan ditolak dengan UNRECOGNIZED_PAYLOAD.

Token non-fungible ERC-721

Di bagian ETHEREUM_TX_V2, Multi-party Compute mendekode metode ERC-721 berikut:

  • 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 dan ERC-721 menggunakan pemilih 4 byte yang sama untuk transferFrom (0x23b872dd) dan approve (0x095ea7b3). Untuk memutuskan apakah argumen uint256 adalah jumlah yang dapat dipertukarkan atau ID token, Multi-party Compute mencari alamat kontrak to di registry kontrak token yang dikenali. Untuk panggilan ERC-721, amount_token_scaled dihilangkan, token_standard adalah "ERC721", dan token_id adalah String berbasis 10. Panggilan ke kontrak yang tidak dikenal dengan salah satu pemilih bersama ini ditolak dengan UNRECOGNIZED_PAYLOAD.

Data yang diketik EIP-712

Untuk payload EIP712_TYPED_DATA_V1 (data berjenis EIP-712 berenkode JSON UTF-8 dengan types, primaryType, domain, dan message), Multi-party Compute memvalidasi struktur JSON dan menghitung ringkasan penandatanganan EIP-712 32 byte, keccak256(0x1901 ++ domainSeparator ++ hashStruct(message)), dengan ++ adalah penyambungan byte. Validasi menolak penyusunan bertingkat yang lebih dalam dari 15 level, jenis siklus, elemen array null, dan kolom domain yang tidak cocok dengan types.EIP712Domain, serta mempertahankan bilangan bulat 256-bit tanpa kehilangan presisi floating point.

Payload EIP712_TYPED_DATA_V1 memproyeksikan atribut berikut:

Atribut Nilai
blockchain Selalu "ETH".
schema Selalu "EIP712_TYPED_DATA_V1".
contract_address domain.verifyingContract, dalam format checksum EIP-55 dengan huruf besar dan kecil. Dihilangkan jika domain tidak menetapkan verifyingContract.
chain_id domain.chainId sebagai Long. Dihilangkan jika domain tidak menetapkan chainId.
max_fee_atomic Selalu 0, karena penandatanganan data yang diketik tidak dikenai biaya jaringan.
secondary_key Untuk jenis pesan yang dikenali, pihak lawan: spender untuk ERC-2612 Permit dan Uniswap Permit2, atau to untuk ERC-3009 TransferWithAuthorization dan Safe SafeTx. Untuk jenis pesan lainnya, domain.verifyingContract.
amount_token_scaled Untuk jenis pesan yang dikenali (Permit, Permit2, TransferWithAuthorization, dan SafeTx), nilai token atau ETH yang diizinkan (value atau details.amount), dalam satuan 10-9. Dihilangkan untuk jenis pesan lainnya.
token_symbol "USDC", "USDT", "DAI", atau "WBTC" saat kontrak verifikasi atau token Permit2 (details.token) adalah token yang dikenali di Ethereum Mainnet. Dihilangkan jika tidak.
deadline Waktu habis masa berlaku pesan, dalam detik sejak epoch Unix, saat pesan memiliki kolom deadline, sigDeadline, atau validBefore. Dihilangkan jika tidak.
eip712 Record dengan data yang diketik. Untuk mengetahui informasi selengkapnya, lihat tabel berikut.

Data eip712 memiliki kolom berikut:

Kolom Jenis cedar Nilai
context.eip712.primary_type String Nama primaryType, misalnya "Permit", "PermitSingle", "TransferWithAuthorization", atau "SafeTx".
context.eip712.domain Record Kolom EIP712Domain yang ditetapkan oleh payload: name, version, chainId, verifyingContract, dan salt.
context.eip712.message Record Kolom message. Nilai bilangan bulat 256-bit (uint256 dan int256) adalah String berbasis 10, sehingga aturan dapat mencocokkan nilai yang tepat tanpa overflow 64-bit.

Bitcoin

Tabel berikut menjelaskan atribut konteks untuk payload BITCOIN_TX_V2 (BIP 174 PSBT v0):

Atribut Nilai
secondary_key Alamat satu output yang tidak berubah. Untuk konsolidasi, yang setiap output-nya adalah kembalian, alamat output pertama.
amount_token_scaled Jumlah yang dikirim ke secondary_key, tidak termasuk kembalian (1 satoshi = 10). 0 untuk konsolidasi.
token_symbol Selalu "BTC".
contract_address Tidak pernah ada.
chain_id Tidak pernah ada, karena PSBT tidak menyatakan jaringan yang dituju. Alamat selalu diformat sebagai alamat Mainnet, sehingga alamat Testnet juga dimulai dengan bc1, 1, atau 3. Awalan alamat menunjukkan jenis alamat, bukan jaringan.
max_fee_atomic Biaya penambang: total input dikurangi total output (1 satoshi = 10).

Agar jaringan Bitcoin tetap terpisah, gunakan kunci yang berbeda untuk setiap jaringan, misalnya di KeyRing untuk Mainnet dan KeyRing lainnya untuk Testnet, serta cakup aturan untuk jaringan tersebut dengan principal_keyring atau principal_key. Kunci yang sama dapat menandatangani di kedua jaringan, jadi ini hanya berfungsi jika Anda tidak pernah menggunakan kunci Mainnet di Testnet.

Transaksi yang mengirim ke lebih dari satu alamat yang bukan merupakan alamat kembalian tidak dapat didekode. Transaksi tanpa alamat tujuan pengiriman, seperti transaksi yang satu-satunya output yang bukan uang kembalian adalah output OP_RETURN, tidak dapat dievaluasi.

Solana

Tabel berikut menjelaskan atribut konteks untuk payload SOLANA_TX_V1 (pesan Solana lama atau v0 yang tidak ditandatangani):

Atribut Nilai
secondary_key Untuk transfer SOL, dompet tujuan. Untuk transfer token, akun token tujuan, bukan dompet yang memilikinya. Dalam base58.
amount_token_scaled Jumlah. Untuk SOL, jumlah lamport (1 lamport = 1). Untuk token, jumlah mentah yang diskalakan dengan desimal yang dibawa oleh petunjuk TransferChecked.
token_symbol "SOL" untuk transfer SOL. Untuk token, "USDC", "USDT", atau "PYUSD"; dihilangkan untuk pencetakan lainnya.
contract_address Untuk transfer token, alamat mint, dalam base58. Dihilangkan untuk transfer SOL.
chain_id Tidak pernah ada. Pesan Solana tidak menyebutkan nama cluster.
max_fee_atomic Jumlah maksimum yang dapat dibayarkan oleh seluruh transaksi dalam lamport: 5.000 untuk setiap tanda tangan yang diperlukan, ditambah biaya prioritas, ⌈batas unit komputasi × harga unit komputasi dalam mikro-lamport ÷ 106⌉, jika transaksi menetapkan harga unit komputasi.

Transaksi Solana dapat berisi beberapa petunjuk:

  • Petunjuk transfer: Program Sistem Transfer (SOL), dan Token SPL atau Token-2022 TransferChecked. Petunjuk Transfer yang tidak dicentang, dan token dengan lebih dari 9 angka desimal, tidak dapat didekode.
  • Petunjuk lainnya: ComputeBudget SetComputeUnitLimit dan SetComputeUnitPrice, Memo (v1 dan v2), Associated Token Account Create dan CreateIdempotent, serta System Program AdvanceNonceAccount. Petunjuk ini tidak menghasilkan konteksnya sendiri.

Setiap petunjuk transfer dievaluasi secara terpisah dengan konteksnya sendiri. Transaksi hanya diizinkan jika setiap transfer diizinkan; jika ada transfer yang ditolak, seluruh transaksi akan ditolak. max_fee_atomic adalah biaya untuk seluruh transaksi dan sama dalam setiap konteks, jadi jangan menjumlahkannya di seluruh transfer.

Jika transaksi menetapkan harga unit komputasi tanpa batas unit komputasi, biaya akan menggunakan batas default Solana sebesar 200.000 unit komputasi untuk setiap instruksi selain instruksi ComputeBudget, hingga 1.400.000.

Penanda tangan transaksi harus cocok dengan akun yang perlu ditandatangani oleh setiap petunjuk, dan akun sumber serta tujuan harus dapat ditulis. Pesan v0 yang menggunakan tabel pencarian alamat tidak dapat didekode. Teruskan byte pesan yang tidak ditandatangani, bukan amplop transaksi yang ditandatangani, di Transaction.payload dan Transaction.rawMessage.

Mint yang dikenali adalah mint Solana Mainnet. Di Devnet atau Testnet, transfer token tidak memiliki token_symbol, jadi periksa contract_address.

Petunjuk Associated Token Account Create mendanai cadangan bebas sewa akun baru di SOL. Jumlah tersebut tidak dalam amount_token_scaled.

Contoh aturan

Contoh berikut adalah kebijakan permit dan forbid yang dapat Anda sesuaikan. Setiap contoh memeriksa setiap atribut opsional dengan has sebelum membacanya.

Batas pembelian untuk KeyRing menggunakan payload dan metadata

Izinkan transfer buy_transaction hingga 500.000 USDC di Ethereum Mainnet dari kunci mana pun di KeyRing institutional-treasury, saat inisiator memberi label transaksi dengan "equities-desk", menetapkan validitas maksimal 300 detik, dan menyatakan nilai maksimal $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"
};

Multi-party Compute tidak memeriksa fiat_amount terhadap payload. Untuk mengetahui informasi selengkapnya, lihat Atribut konteks.

Batas pembelanjaan untuk satu kunci

Izinkan transfer ETH hingga 1 ETH dari satu kunci di Ethereum Mainnet. !(context has contract_address) mengecualikan panggilan kontrak yang mengirim 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
};

Daftar stablecoin yang diizinkan di Ethereum

Izinkan transfer hingga 5.000 USDC ke satu alamat, dan persetujuan (tunjangan) hingga 5.000 USDC untuk alamat tersebut. Kebijakan ini memeriksa contract_address, bukan token_symbol, sehingga token dari kontrak lain yang menggunakan simbol yang sama tidak cocok:

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 adalah "USDC" untuk transaksi ini.

Transfer ERC-721 dan penjaga persetujuan operator

Izinkan transfer satu surat utang negara yang ditokenisasi (token_id == "1042") dari kontrak ERC-721 yang disetujui ke alamat penyelesaian, dan larang pemberian persetujuan operator di seluruh koleksi (setApprovalForAll dengan approve_all == true).

Kebijakan A mengizinkan satu transfer 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"
};

Kebijakan B melarang persetujuan operator di seluruh koleksi:

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

Batas izin USDC tanpa gas EIP-712

Izinkan penandatanganan Permit ERC-2612 off-chain hingga 25.000 USDC di Ethereum Mainnet untuk router penyelesaian yang disetujui, jika izin berakhir sebelum waktu tertentu:

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

Batas pembelanjaan dan batas biaya Bitcoin

Izinkan transfer hingga 0,0025 BTC dengan biaya penambang hingga 10.000 satoshi, dari kunci di KeyRing yang hanya Anda gunakan di 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
};

Batas biaya prioritas dan transfer SOL

Izinkan transfer SOL hingga 1,5 SOL jika total biaya, termasuk biaya prioritas, maksimal 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
};

Transfer token SPL atau Token-2022 di Solana

Mengizinkan transfer hingga 250 USDC ke satu akun token. Aturan yang sama cocok dengan program SPL Token dan Token-2022, karena konteksnya tidak menyebutkan program mana yang digunakan transfer:

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 adalah akun token penerima untuk mint ini. Untuk mengizinkan dompet penerima, cantumkan akun tokennya untuk setiap mint yang Anda izinkan. Dalam transaksi dengan beberapa transfer, aturan ini harus cocok dengan setiap transfer.

Blok aset tidak dikenali

Tolak transfer apa pun yang asetnya tidak dikenali oleh Multi-party Compute. Kebijakan forbid ini hanya menggunakan has, sehingga tidak akan gagal dievaluasi:

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

Batas biaya untuk blockchain

max_fee_atomic selalu ada, sehingga kebijakan forbid ini tidak akan gagal dievaluasi. Karena skalanya adalah 10-9 dari setiap koin native, angka yang sama memiliki nilai yang berbeda di setiap blockchain. Cakup kebijakan ke satu blockchain:

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

Tindakan ini menolak transaksi Ethereum yang dapat membayar biaya lebih dari 0,01 ETH.

KeyRing

KeyRing adalah penampung statis yang mengelompokkan kunci MPC, misalnya "institutional-treasury" atau "btc-cold-storage". Setiap kunci dibuat di dalam satu KeyRing dan tetap berada di KeyRing tersebut secara permanen.

KeyRing berpartisipasi dalam kebijakan dengan tiga cara:

  • KeyRing KeyPolicy (kuorum penandatanganan). Saat membuat KeyRing, Anda menetapkan KeyPolicy yang tidak dapat diubah, yang menentukan hierarki nilai minimum tim dan pengguna yang memiliki key share dan harus menyetujui sebelum kunci apa pun di KeyRing dapat menandatangani. Kebijakan transaksi berfungsi bersama KeyPolicy: kebijakan transaksi mengevaluasi aturan bisnis untuk payload (PERMIT atau DENY), sedangkan KeyPolicy KeyRing mengatur pembagian kunci siapa yang harus mengizinkan upacara penandatanganan.
  • Menentukan cakupan kebijakan transaksi dengan menandatangani KeyRing (context.principal_keyring). Setiap konteks transaksi mencakup context.principal_keyring, yang ditetapkan ke ID KeyRing yang menyimpan kunci penandatanganan, dan context.principal_key, yang ditetapkan ke ID kunci penandatanganan. Aturan dengan context.principal_keyring == "institutional-treasury" berlaku untuk setiap kunci di KeyRing, termasuk kunci yang dibuat di KeyRing tersebut nanti, tanpa membuat atau menyetujui kebijakan baru:

    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
    };
    
  • Daftar yang diizinkan KeyRing tujuan (dalam KeyList). Anda juga dapat menambahkan KeyRing sebagai entri dalam KeyList, sehingga transfer ke alamat blockchain dari kunci aktif apa pun dalam KeyRing tersebut, seperti pembersihan internal antara KeyRing hot dan cold, diizinkan secara otomatis saat kunci baru dibuat. Misalnya, lihat Daftar yang diizinkan dan daftar yang tidak diizinkan KeyList.

Daftar yang diizinkan dan daftar yang tidak diizinkan KeyList

Izinkan transfer hingga 1 ETH hanya ke alamat di trusted-destinations KeyList. context.key_lists["trusted-destinations"] adalah kumpulan alamat yang diperluas oleh KeyList pada createTime transaksi, sehingga menambahkan atau menghapus entri akan mengubah apa yang diizinkan oleh aturan ini tanpa kebijakan baru:

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

Tolak transaksi apa pun ke alamat di KeyList blocked-addresses, di setiap blockchain. key_lists dan secondary_key selalu ada, dan CreateTransactionPolicy memverifikasi bahwa KeyList ada, sehingga kebijakan forbid ini tidak akan gagal dievaluasi:

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

Tulis ID KeyList dalam sintaksis tanda kurung, context.key_lists["..."], bukan sintaksis titik. Sintaksis titik gagal mengurai ID yang berisi tanda hubung atau diawali dengan angka. Entri dibandingkan sebagai string, jadi tambahkan entri manual dalam format alamat yang dijelaskan tabel untuk setiap blockchain. Untuk mengetahui informasi selengkapnya, lihat KeyList dalam konteks Cedar.