For the complete documentation index, see llms.txt. This page is also available as Markdown.

Membangun di Bloom

Panduan ini menjawab satu pertanyaan: bagaimana seorang builder melakukannya sendiri? Ambil kontrak aset dunia nyata Solidity, jalankan di chain Rome sebagai token berizin, buka aksesnya ke dompet Solana maupun dompet EVM tanpa bridge dan tanpa token kedua, dan sambungkan keputusan KYC/kepatuhan Anda sendiri.

Audiensnya adalah developer yang mengevaluasi atau mengadopsi pendekatan ini. Bloom adalah contoh kerja yang digunakan sepanjang panduan — aset live-nya ARCV ("Mineral Vault I") di Hadrian (200010) adalah contoh nyata dari setiap langkah di bawah ini, dan tanda terima deployment-nya (deployments/200010.tokens/ARCV.json) mencatat tiga kontrak dan delapan transaksi persis yang dihasilkan metode ini.

Tidak ada di sini yang memodifikasi kontrak aset. Bloom menjalankan framework Arc milik Plume tanpa modifikasi (pohon vendored di contracts/, identik byte demi byte dengan plumenetwork/contracts pada pin di NOTICE); satu-satunya kontrak di sisi Rome adalah ArcTokenFactoryV2, yang menambahkan satu fungsi. Pekerjaannya ada pada bagaimana Anda mendeploy dan bagaimana Anda mengendalikan kontrak-kontrak itu — bukan mengubahnya.

Metodenya, sekilas. Token berizin adalah tiga kontrak yang dideploy. Itu dideploy secara bertahap — satu kontrak per transaksi — karena panggilan factory satu transaksi melebihi batas akun per transaksi di Rome. Proxy-nya harus berasal dari artefak yang terkunci provenance atau registrasi on-chain gagal tertutup. Kepatuhan adalah satu boolean per alamat, ditulis oleh siapa pun yang diotorisasi proses KYC Anda. Dan deployment yang sama dapat diakses dari dompet Solana melalui pengirim sintetis yang diturunkan di chain — tanpa bridge, tanpa wrapped token, tanpa allowlist kedua.

Prasyarat

Semua alat referensi berada di scripts/ (jalankan npm install di sana terlebih dahulu). Setiap perintah mengambil fakta chain dari registry, bukan meng-hardcode-nya, jadi mengalihkan ke chain Rome lain adalah perubahan environment, bukan perubahan kode:

export PRIVATE_KEY=# kunci deployer/issuer yang didanai di chain target
export CHAIN_ID=200010     # memilih chain
export REGISTRY_ROOT=# checkout dari registry chain Rome
# Alur jalur Solana juga membutuhkan:
export SOLANA_KEYPAIR=# path ke JSON keypair Solana yang didanai (pembayar biaya)

Gas pada chain Rome didenominasikan dalam USDC; rangkaian deployment penuh biayanya sekitar 10–15 unit native di devnet. Kunci hanya berasal dari environment — jangan pernah dari repo. Build kontrak sekali sebelum mendeploy, karena artefak harus berasal dari rome-contracts/out (lihat langkah 3):

cd contracts       && forge build --via-ir     # suite Arc yang vendored
cd rome-contracts  && forge build --via-ir     # ArcTokenFactoryV2 + proxy kanonik

Langkah 1 — Pahami apa itu token berizin adalah di sini

Token Bloom berizin bukan satu kontrak. Itu adalah tiga kontrak yang dideploy, plus empat kontrak bersama yang dideploy ops sekali per chain dan dipakai ulang oleh setiap issuer.

Tiga kontrak per token — satu aset memiliki tepat ini:

Kontrak
Sumber
Apa itu

ArcTokenProxy

contracts/src/proxy/ArcTokenProxy.sol

Token itu sendiri — proxy UUPS yang menunjuk ke ArcToken implementasi bersama. Saldo, pemegang, dan peran berada di sini.

WhitelistRestrictions

contracts/src/restrictions/WhitelistRestrictions.sol

Modul allowlist. Satu boolean per alamat; ditegakkan pada setiap transfer saat aset digated.

YieldBlacklistRestrictions

contracts/src/restrictions/YieldBlacklistRestrictions.sol

Modul yield. Mengecualikan alamat dari distribusi yield tanpa menyentuh kepemilikannya.

Empat kontrak bersama, satu per chain (dideploy oleh deploy-infra.ts):

Kontrak
Peran

RestrictionsRouter

Registry tipe modul — wiring chain, diatur sekali oleh ops.

ArcTokenFactoryV2

Registrasi + codehash proxy kanonik (langkah 2–3).

ArcToken (implementasi)

Logika aset bersama yang dapat digunakan ulang yang diproksikan oleh setiap token.

ArcTokenPurchase

Satu storefront, dibagi oleh setiap token dan issuer (langkah 4).

wUSDC

Sisi kas — mata uang yield dan mata uang jual-beli.

Pembatasan transfer dan pembatasan yield adalah modul yang sengaja dipisahkan: seorang pemegang dapat dilarang menerima pendapatan sambil tetap memegang aset, seperti itulah sanksi dan perintah pengadilan memang bekerja.

Fakta "tiga kontrak" ini sangat penting bagi verifikasi. verify-deployments.ts dan register-asset.ts keduanya mengharapkan token mengarah ke tiga kontrak yang dideploy — verifikasi manual sekali melewatkan tujuh di antaranya di seluruh chain (setiap modul yield dan tiga modul whitelist).

Siklus hidupnya memiliki tiga fase dan satu jalan satu arah:

Penggatingan bersifat satu arah untuk suplai karena mint dan burn melewati address(0) sebagai lawan transaksi, dan address(0) tidak pernah bisa masuk allowlist — jadi setelah digated, suplai baru tidak akan pernah bisa dicetak. Itulah jaminan yang diberikan aset berizin kepada para pemegangnya.


Langkah 2 — Deploy secara bertahap, jangan pernah sebagai satu transaksi

Arc menyediakan satu kali jalan createToken yang mendeploy proxy dan kedua modul serta menyambungkannya dalam satu panggilan. Di Rome Anda tidak bisa menggunakannya. Transaksi itu membutuhkan 77 account lock Solana, dan batas per transaksi Rome adalah 62 lock. Itu tidak akan pernah muat — tidak dengan penyesuaian, tidak dengan pass optimisasi.

Jadi deployment-nya adalah secara bertahap: setiap kontrak dalam transaksinya sendiri, dan token memperoleh status setara factory melalui ArcTokenFactoryV2.registerToken alih-alih monolitik createToken. Ini adalah wizard pembuatan, dan itulah yang dilakukan konsol issuer langkah demi langkah:

wizard pembuatan

Implementasi referensinya adalah arc/plan/create.ts (createSequence()), yang dirender aplikasi sebagai enam kartu (bloom/lib/createCards.ts) di atas delapan transaksi, sesuai urutan persis yang dipaksakan oleh kontrak:

#
Transaksi
Panggilan kontrak

1

Deploy aset

new ArcTokenProxy(impl, initData) di mana initData = ArcToken.initialize(...)

2

Deploy modul allowlist

new WhitelistRestrictions()

3

Tetapkan Anda sebagai administratornya

whitelist.initialize(issuer)

4

Tegakkan pada transfer

token.setRestrictionModule(TRANSFER, whitelist)

5

Deploy modul yield

new YieldBlacklistRestrictions()

6

Tetapkan Anda sebagai administratornya

yieldBlacklist.initialize(issuer)

7

Tegakkan pada yield

token.setRestrictionModule(YIELD, yieldBlacklist)

8

Daftarkan ke factory

factoryV2.registerToken(token, impl)

Bentuk skripnya adalah satu perintah:

Issuer (PRIVATE_KEY) menandatangani setiap transaksi dan akhirnya memegang peran token (ArcToken.initialize memberikan kepada msg.sender — lihat langkah 7). Registrasi (tx 8) adalah yang membuka enableToken dan setiap upgrade yang dimediasi factory.

Jangan "mengoptimalkan" ini kembali menjadi monolit. Menggabungkan panggilan ini ke dalam satu transaksi untuk menghemat round-trip justru memperkenalkan kembali overflow 62-lock yang ingin dihindari jalur bertahap. Batas yang sama itulah alasan distribusi yield berjalan satu pemegang per transaksi (langkah 8). Jika sebuah panggilan gagal dengan Terlalu banyak akun: N > 62, satu transaksi menyentuh terlalu banyak akun — pecah saja, jangan disetel.


Langkah 3 — Deploy proxy hanya dari artefak yang terkunci provenance

registerToken adalah batas keamanan yang membuat deployment bertahap aman. Ini hanya akan menerima token yang runtime codehash-nya cocok dengan yang kanonik ArcTokenProxy yang ditanam ke dalam factory saat deployment:

Karena codehash itu adalah immutable, proxy yang dibangun dari artefak lain mana pun gagal tertutup dengan ProxyCodehashUnknown. Dua aturan berikut berlaku, dan keduanya ditegakkan oleh CI dan aturan keras dalam CLAUDE.md:

  1. Proxy token HARUS dideploy dari rome-contracts/out — jangan pernah dari contracts/out, jangan pernah dari build lain. Itulah kompilasi yang dipin oleh codehash kanonik factory.

  2. bytecode_hash = "none" dan cbor_metadata = false di rome-contracts/foundry.toml sangat penting. Dengan metadata diaktifkan, runtime ArcTokenProxy runtime yang tertanam di factory (type().runtimeCode) membawa ekor CBOR/IPFS yang berbeda dari artefak mandiri out/ yang menjadi sumber deployment wizard — jadi di chain registerToken melakukan revert sementara setiap tes Foundry dalam source lulus (Foundry menyematkan kedua salinan, jadi tidak bisa melihat ketidakcocokan). rome-contracts/test/ArtifactProvenance.t.sol mengunci properti ini; run yang didanai-lah yang awalnya menangkapnya.

Suite in-source yang hijau tidak membuktikan provenance. Sebelum mengirim image, dan setelah perubahan setting compiler APAPUN, buktikan properti ini terhadap yang dideploy factory (read-only, tanpa kunci):

Ini menghitung hash atas ArcTokenProxy artefak lokal Anda dan memastikan hash itu muncul persis di dalam bytecode factory yang dideploy.

Jika setting compiler harus diubah, rotasikan factory — deploy yang baru dengan immutable yang mem-pin codehash baru, dan lakukan rewiring — alih-alih mem-patch pengecekan secara manual:

Rotasi mempertahankan alamat lama dalam receipt; token yang terdaftar pada factory lama harus mendaftar ulang pada factory baru.


Langkah 4 — Buka penjualan melalui storefront bersama

Menjual adalah tindakan terpisah dari membuat, dan berjalan pada satu ArcTokenPurchase storefront bersama. Tiga hal harus benar sebelum penjualan dibuka, dan ArcTokenPurchase.enableToken memeriksa masing-masing di chain:

Ada persyaratan keempat yang tersirat yang dipaksakan oleh aset yang digate: karena setiap transfer melewati gate allowlist, memindahkan inventaris ke storefront hanya berhasil jika alamat storefront itu sendiri ada di whitelist token Anda. Jadi urutan lengkap membuka penjualan adalah:

  1. Masukkan storefront ke whitelist pada modul whitelist token Anda (batchAddToWhitelist([storefront]) — lihat langkah 5). Tanpa ini, transfer inventaris pada (2) akan revert TransferRestricted() setelah digate.

  2. Transfer inventaris ke alamat storefront (dari receipt infra arcTokenPurchase).

  3. enableToken(token, amount, price) — pembeli kini membayar wUSDC dan menerima RWA.

Pembagian penarikan layak diketahui pada storefront bersama, dan ini tidak simetris (arc/roles.ts adalah otoritasnya):

Tindakan
Otoritas
Dimiliki oleh

enableToken / disableToken / withdrawUnsoldArcTokens

token ADMIN_ROLE (onlyTokenAdmin)

Anda, issuer-nya

withdrawPurchaseTokens (hasil wUSDC)

storefront DEFAULT_ADMIN_ROLE

siapa pun yang mendeploy storefront

Pada chain self-hosted Anda adalah keduanya. Pada storefront bersama, kumpulan hasil adalah pendapatan semua issuer, jadi penarikannya berada di level platform — rancang settlement Anda berdasarkan itu, bukan dengan mengasumsikan kontrol sepihak.


Langkah 5 — Sambungkan KYC / kepatuhan Anda sendiri

Ini adalah bagian yang dibaca pelanggan sebelum setuju, jadi ini kode, bukan prosa. Kepatuhan ditegakkan oleh kontrak token itu sendiri — bukan oleh penyaringan off-chain, filter sequencer, atau kebijakan venue. Aturan-aturan itu ikut bersama token ke jalur eksekusi apa pun, pada kedua jalur dompet. Yang dicatat chain adalah hasil dari keputusan KYC Anda, sebagai satu boolean:

Interface yang ditulis oleh proses Anda

Keputusan setuju/tolak dari vendor KYC Anda menjadi tepat salah satu panggilan ini:

Siapa yang boleh menulis

Otoritas yang dibutuhkan sebuah persetujuan adalah MANAGER_ROLE pada modul — bukan ADMIN_ROLE pada token. addToWhitelist / batchAddToWhitelist / removeFromWhitelist semuanya onlyRole(MANAGER_ROLE), dan peran itu berada pada WhitelistRestrictions Mengautentikasi ADMIN_ROLE pada token lalu menulis ke modul adalah cacat nyata yang sudah pernah harus ditanggung codebase ini. Jangan tawarkan WHITELIST_ADMIN_ROLE sebagai perbaikan atas penolakan — itu diberikan saat initialize dan tidak diperiksa di mana pun dalam suite (arc/roles.ts menegaskan bahwa itulah satu-satunya peran yang tidak mengunci apa pun).

WhitelistRestrictions.initialize(issuer) (tx 3 dari wizard) memberikan issuer DEFAULT_ADMIN_ROLE, ADMIN_ROLE, MANAGER_ROLE, WHITELIST_ADMIN_ROLE, dan UPGRADER_ROLE pada modul itu. Jadi issuer memegang MANAGER_ROLE secara bawaan dan juga dapat mendelegasikannya: karena issuer memegang DEFAULT_ADMIN_ROLE, sebuah grantRole(MANAGER_ROLE, serviceAccount) menyerahkan penulisan ke penanda tangan backend.

Sebuah keputusan menjadi penulisan on-chain

Arahkan webhook vendor Anda ke penanda tangan yang memegang MANAGER_ROLE, dan saat ada approve, batch alamat-alamatnya:

Tentukan whitelistModule dari token itu sendiri (ArcToken.getRestrictionModule(TRANSFER_RESTRICTION_TYPE)), bukan dari proyeksi yang di-cache — mengarahkan penulisan ke modul yang salah adalah bagaimana "approve pada aset apa pun" pernah menulis ke allowlist satu token.

Varian yang ditandatangani wallet (demo swadaya)

Untuk deployment uji tanpa izin tempat pengunjung mendaftarkan diri sendiri, berikan MANAGER_ROLE kepada sebuah TestApprover (rome-contracts/src/TestApprover.sol) yang modul adalah immutable. Lalu approve(address) dapat dipanggil oleh siapa pun, dari wallet mereka sendiri, membayar gas mereka sendiri — ini memanggil addToWhitelist hanya jika alamat tersebut belum terdaftar:

Ini adalah "gerbang masuk" — ini menunjukkan kepada pengunjung mekanisme sebenarnya (sebuah approval menjadi entri allowlist on-chain yang kemudian ditegakkan token) tanpa mengasuh apa pun. Jangan pernah berikan MANAGER_ROLE kepada sebuah TestApprover pada token produksi — ini membuat allowlist token itu tanpa izin.

Saat gerbang mulai berlaku, dan mengganti penyedia

Gerbang hanya membatasi setelah aset digate (setTransfersAllowed(false), ADMIN_ROLE pada modul). Selama belum digate, transfer terbuka — bangun allowlist Anda dulu, lalu gate. Setelah digate, transfer di mana salah satu pihak tidak ada di daftar akan revert dengan error bertipe TransferRestricted() (0xe827105e).

Mengganti penyedia KYC di kemudian hari tidak memerlukan perubahan on-chain. Modul allowlist, antarmukanya, dan boolean yang disimpannya bersifat agnostik terhadap penyedia. Untuk berganti vendor, arahkan sumber keputusan yang berbeda ke MANAGER_ROLE penanda tangan yang sama — tanpa redeploy, tanpa migrasi, tanpa perubahan state. Chain tidak pernah tahu vendor mana yang membuat panggilan, hanya hasilnya.


Langkah 6 — Buka aset yang sama untuk wallet Solana

Tiga kontrak yang sama dapat dijangkau dari wallet Solana tanpa bridge dan tanpa token kedua. Pengguna native Solana tidak memiliki kunci EVM di mana pun; sebagai gantinya identitas EVM mereka adalah sintetis, diturunkan on-chain dari penanda tangan Solana yang sebenarnya dari transaksi:

Program Rome EVM menurunkan ini dari penanda tangan itu sendiri (do_tx_unsigned::derive_sender), jadi ini tidak bisa dipalsukan dan tidak ada kunci privat secp256k1 untuknya — tanda tangan Solana adalah satu-satunya hal yang dapat mengendalikan alamat ini. Derivasi referensinya ada di arc/materialise/solana/identity.ts (syntheticAddress), kompatibel byte-wise dengan aturan on-chain:

Apa yang dilakukan builder untuk mendukung jalur ini — perhatikan bahwa tidak satu pun dari ini merupakan perubahan kontrak:

  1. Whitelist pengguna Solana berdasarkan alamat sintetis mereka. Bagi lapisan kepatuhan, alamat sintetis adalah alamat biasa: tempel pubkey Solana pengguna, turunkan sintetisnya, dan batchAddToWhitelist([synthetic]). Satu allowlist mencakup kedua dunia wallet.

  2. Sediakan signing PDA sekali, sebelum transaksi pertama mereka. PDA otoritas eksternal yang mengesahkan tanda tangan sintetis harus sudah ada terlebih dahulu, dan membuatnya adalah panggilan jalur EVM (create_pda) — pengguna yang hanya memakai Solana tidak dapat melakukannya sendiri, jadi issuer yang menyediakannya. Penyediaan adalah external_auth, bukan lazy.

  3. Kirim melalui pustaka lane, bukan secara manual. submitDoTxUnsigned (arc/materialise/solana/submit.ts) membangun sebuah DoTxUnsigned instruksi — sebuah tanpa tanda tangan payload EIP-1559 yang diotorisasi oleh tanda tangan Solana — dan menangani empat hal yang sering salah pada transaksi buatan tangan:

    • Penemuan akun melalui rome_emulateCallAccounts, yang menentukan dapat-tidaknya setiap akun ditulis. Nilai value harus harus diteruskan ke discovery, atau transfer value menandai PDA saldo penerima sebagai read-only dan gagal on-chain.

    • Anggaran komputasi — sebuah DoTxUnsigned membutuhkan heap frame 250 KB dan 1,35 juta CU batas (EVM Rome melampaui default 32 KB / 200 K); menyisakan headroom sekitar 50 K di bawah batas 1,4 M Solana.

    • PDA wallet kas (fee), ditambahkan sebagai writable — discovery tidak menyertakannya.

    • Fallback v0 + lookup-table. Saat akun sebuah panggilan melampaui envelope transaksi legacy 1232 byte, klien mengirim ulang sebagai transaksi v0 melalui address lookup table baru. (Diukur hari ini, pembelian storefront muat dalam envelope legacy pada ~1.061 dari 1232 byte; pemegang baru yang associated token account-nya masih harus dibuat bisa melampauinya.)

Pengguna adalah pembayar fee dan membayar lamports (SOL) dari wallet Solana mereka; sintetis yang mereka kendalikan memegang aset dan tidak pernah memegang SOL. Setelah setiap pengiriman lane, polling nonce EVM sebelum yang berikutnya — indexer sedikit tertinggal dari konfirmasi Solana.

Jalur ini HANYA ATOMIK. Sebuah DoTxUnsigned adalah satu transaksi EVM yang dieksekusi di dalam satu transaksi Solana oleh atomic VM Rome. Iterative VM (satu eksekusi EVM yang di-staging di beberapa transaksi Solana) adalah belum dapat dijangkau melalui jalur ini. Panggilan yang tidak muat secara atomik sama sekali tidak bisa memakai jalur ini — perbaikannya adalah panggilan yang lebih kecil, bukan fallback. Perhatikan bahwa fallback v0+ALT adalah envelope, bukan eksekusi yang berbeda; itu tetap satu transaksi atomik.

Mengapa RWA tidak bisa bocor keluar dari perimeter. Aset ini berada sebagai state EVM — saldonya adalah storage di dalam akun program EVM Rome. Tidak ada mint SPL darinya dan tidak ada sesuatu native Solana untuk dipindahkan; primitive pemindahan aset pada jalur ini beroperasi pada akun token SPL, sedangkan saldo storage EVM tidak memilikinya. Setiap perpindahan yang bisa diekspresikan tanda tangan Solana adalah panggilan ke kontrak token, yang menjalankan gerbang allowlist — suite yang didanai menegaskan bahwa transfer ke alamat yang tidak di-whitelist revert identik baik ditandatangani dengan kunci EVM maupun kunci Solana. Jalur kas (wUSDC) adalah pengecualian yang disengaja: ia didukung SPL dan memang disweep keluar ke akun token milik pengguna sendiri.


Langkah 7 — Ketahui siapa yang memegang otoritas setelah deploy

ArcToken.initialize berjalan dari konstruktor proxy (tx 1) dan memberikan peran kepada msg.sender — driver wizard, yaitu issuer. Ini memberikan lima peran secara eksplisit:

Dua konsekuensi yang tidak boleh terlewat oleh builder:

  • MINTER_ROLE, BURNER_ROLE, dan UPGRADER_ROLE TIDAK diberikan saat initialize. Pasokan awal dicetak di dalam initialize (sebuah internal _mint, tidak perlu peran), tetapi kemudian mint atau burn mengharuskan issuer terlebih dahulu memberikan peran itu kepada diri mereka sendiri. Mereka bisa, karena mereka memegang DEFAULT_ADMIN_ROLE (admin dari setiap peran — tidak ada yang memanggil _setRoleAdmin, jadi DEFAULT_ADMIN_ROLE mengadministrasikan semuanya). Tetapi itu adalah langkah ekstra yang disengaja, bukan kekuatan yang otomatis tersedia.

  • UPGRADER_ROLE tidak pernah diberikan kepada factory. Peningkatan yang dimediasi factory (ArcTokenFactoryV2.upgradeToken) memerlukan factory itu sendiri untuk memegang UPGRADER_ROLE pada token — memberikannya kepada diri sendiri tidak berpengaruh. Pemberian itu adalah pintu satu arah yang tidak bisa dibalik oleh factory, jadi sifatnya opt-in: jika Anda ingin peningkatan yang dimediasi factory, grantRole(UPGRADER_ROLE, factory) secara eksplisit; jika tidak, issuer yang meningkatkan token secara langsung.

Model 21-otoritas lengkap (11 nama peran di enam kontrak — nama yang sama adalah otoritas berbeda di tiap kontrak) dikodifikasi dalam arc/roles.ts. Tanyakan rolesRequiredFor(contract, functionName) daripada membaca kontrak milik peran itu sendiri, karena empat fungsi storefront dan kedua fungsi factory dikunci oleh otoritas yang berada pada kontrak yang berbeda .


Langkah 8 — Distribusikan yield

Token membayar yield dalam wUSDC (ditetapkan pada initialize, dapat diubah melalui setYieldToken di bawah YIELD_MANAGER_ROLE). Distribusi menelusuri himpunan holder:

Mekanisme yang penting untuk menjalankannya dengan benar:

  • Seluruh totalAmount diambil dari pemanggil hanya pada startIndex == 0 jendela (safeTransferFrom(msg.sender, this, totalAmount)). Approve total itu ke token sebelum jendela pertama; jendela berikutnya membayar dari saldo yang sudah dipegang.

  • nextIndex berputar ke 0 saat penelusuran selesai. Loop distributeYieldWithLimit(total, nextIndex, …) sampai nextIndex kembali 0.

  • Bagian holder yang dibatasi yield tetap berada di kontrak token — mereka dilewati, bukan didistribusikan ulang.

Di Rome batas praktisnya adalah maxHolders = 1 per transaksi — batas 62 akun yang sama dari langkah 2 — jadi yield ditelusuri satu holder per transaksi (terukur ~318 K gas per holder). Setiap holder yang di-whitelist, baik EVM maupun native Solana, menerima secara proporsional; skrip referensinya adalah measure-yield-batch.ts dan langkah yield pada smoke yang didanai menegaskannya end-to-end.


Langkah 9 — Verifikasi apa yang Anda deploy

Tidak ada yang secara otomatis mengirim source ke mana pun di Rome, jadi verifikasi adalah langkah yang Anda jalankan. Setelah deploy apa pun — infrastruktur atau token baru — jalankan verifier yang read-only, tanpa kunci, dan idempoten (kontrak yang sudah terverifikasi dilewati, jadi menjalankannya ulang setelah menerbitkan token hanya memverifikasi yang baru):

Ia mengharapkan tiga kontrak per token (proxy + kedua modul) plus infrastrukturnya, dan melaporkan apa yang tidak bisa diverifikasi alih-alih membuat deploy gagal. Melakukan ini secara manual sekali membuat tujuh kontrak terlewat.

Mendaftarkan aset ke registry Rome memperlakukan verifikasi sebagai gerbang, bukan dekorasi (register-asset.ts) : token memperoleh apps/arc/<chain>.json catatan — membawa standard: arc-permissioned-erc20 dan transferRestriction yang menamai gerbang allowlist-nya — hanya ketika ketiga kontraknya terverifikasi di Sourcify. Catatan itu membaca chain untuk faktanya (token yang dideploy lewat wizard tidak memiliki receipt yang dikomit) dan hanya menulis checkout registry lokal; mengajukan PR adalah tugas manusia.

Untuk bukti end-to-end dari seluruh loop — buat, whitelist, gate, jual di kedua jalur, distribusikan yield — jalankan smoke yang didanai pada chain mana pun:


Langkah 10 — Ketahui apa yang tetap off-chain

Model kepercayaan ini sengaja jujur, dan builder sebaiknya menyajikannya dengan cara yang sama kepada penggunanya sendiri:

  • Flag allowlist adalah keputusan off-chain Anda. KYC/AML terjadi dalam proses Anda — vendor Anda, aturan Anda. Chain hanya mencatat dan menegakkan hasil, isWhitelisted(addr).

  • Satu-satunya state on-chain adalah satu boolean per alamat. Tidak ada PII, tidak ada dokumen, tidak ada klaim identitas, tidak ada attestation on-chain, tidak ada bukti kriptografis tentang siapa pemilik sebuah alamat. Ini adalah model Arc yang digunakan di Plume; model ini menukar transfer yang lebih berat dari standar identitas on-chain (mis. ERC-3643) dengan mekanisme yang lebih ringan dan kepercayaan yang dipegang issuer.

  • Pemulihan adalah kekuasaan issuer, bukan jalan keluar darurat. Wallet yang hilang — EVM atau Solana — dipulihkan dengan me-whitelist alamat pengganti dan, jika perlu, menggunakan mint/burn/upgrade di bawah proses hukum Anda sendiri (Arc tidak memiliki primitive forced-transfer bawaan). Karena itu, kustodi kunci issuer adalah bagian dari posture kepatuhan.

  • Tidak ada relayer, tidak ada permukaan kustodi. Pengguna memegang gas mereka sendiri di kedua jalur. Layanan fee-payer berarti memegang kunci — permukaan yang seharusnya tidak ditambahkan oleh produk RWA.


Referensi: tooling

Setiap skrip dijalankan dari scripts/ setelah npm install, dengan PRIVATE_KEY, CHAIN_ID, dan REGISTRY_ROOT diekspor.

Skrip
Apa fungsinya

deploy-infra.ts

Sekali per chain: empat kontrak bersama, dikonfigurasi untuk wUSDC.

create-token.ts

Wizard bertahap — delapan transaksi, satu token.

rotate-factory.ts

Deploy factory baru setelah perubahan compiler/artifact; sambungkan ulang.

verify-artifact-provenance.ts

Buktikan artifact proxy Anda diterima oleh factory yang dideploy (read-only).

verify-deployments.ts

Verifikasi ketiga kontrak per token + infrastruktur di Sourcify (read-only).

register-asset.ts

Verifikasi gerbang, lalu siapkan catatan kepatuhan registry.

measure-yield-batch.ts

Ukur ulang batas yield per tx pada sebuah chain.

smoke.ts

Suite end-to-end yang didanai di kedua jalur.

sweep-synthetic-native.ts

Ambil kembali gas native dari akun sintetis (kebersihan pengujian).

Latar belakang yang lebih mendalam tersedia bersama panduan ini: docs/ARCHITECTURE.md (model aplikasi berlapis), docs/LANES.md (kedua jalur dan kustodi), docs/COMPLIANCE.md (model kepercayaan), dan docs/USAGE.md (runbook operator).

Terakhir diperbarui

Apakah ini membantu?