Skip to main content

๐Ÿ“ค Unit 3 โ€” Build & Deploy CosmWasm

Goal Unit Ini

Di akhir unit ini kamu akan:

  • Bisa meng-optimize contract menjadi Wasm siap deploy
  • Punya injectived terkonfigurasi untuk testnet
  • Berhasil store contract dan mendapat code_id
  • Berhasil instantiate dan mendapat alamat contract
  • Bisa execute dan query contract dari terminal
Prasyarat
  • โœ… Unit 2 selesai โ€” contract counter sudah lolos cargo test
  • โœ… Docker terpasang dan berjalan โ€” dibutuhkan untuk optimizer
  • โœ… Punya testnet INJ (lihat Phase 0 Unit 4)
Unit ini paling rawan macet

Toolchain CosmWasm punya lebih banyak bagian bergerak daripada Hardhat: Docker, binary chain, konfigurasi key. Sisihkan waktu yang cukup dan jangan mengerjakannya di malam sebelum deadline.

Kalau macet lebih dari 30 menit di satu langkah, tanya di grup Telegram. Kemungkinan besar peserta lain mengalami hal yang sama.


๐Ÿ“Š Alur Lengkapnyaโ€‹


๐Ÿ”จ Step 1 โ€” Compile ke Wasmโ€‹

Dari dalam folder project:

cargo wasm

Ini menghasilkan file Wasm, tapi belum siap deploy โ€” ukurannya masih terlalu besar.


๐Ÿ“ฆ Step 2 โ€” Optimize dengan Dockerโ€‹

Chain membatasi ukuran contract, jadi Wasm harus dikecilkan dulu. Optimizer resmi berjalan di Docker dan menghasilkan build yang deterministik โ€” orang lain yang mengompilasi kode yang sama akan mendapat file yang identik.

Intel / AMD (x86_64)
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/rust-optimizer:0.12.12
Apple Silicon / ARM64
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/rust-optimizer-arm64:0.12.12

Hasilnya ada di folder artifacts/:

ls -lh artifacts/

Kamu akan melihat file .wasm berukuran ratusan kilobyte.

Build ARM64 tidak identik dengan x86

Kalau kamu di Apple Silicon, file Wasm hasilmu bisa berbeda checksum dari hasil build x86. Untuk latihan camp ini tidak masalah.

Untuk deployment mainnet sungguhan yang butuh verifikasi reproducible, gunakan build x86_64.

Versi optimizer

Perintah di atas memakai cosmwasm/rust-optimizer:0.12.12 sesuai dokumentasi Injective per 30 Juli 2026. CosmWasm juga merilis image dengan nama cosmwasm/optimizer untuk versi yang lebih baru.

Kalau perintah di atas gagal karena image tidak ditemukan, cek dokumentasi CosmWasm resmi untuk versi terkini, lalu laporkan di Telegram supaya halaman ini diperbarui.


๐Ÿ–ฅ๏ธ Step 3 โ€” Pasang injectivedโ€‹

injectived adalah CLI resmi untuk berinteraksi dengan Injective chain.

Ikuti panduan instalasi resmi di docs.injective.network โ€” cari bagian instalasi injectived. Cara pemasangan berbeda antar sistem operasi dan versinya diperbarui berkala, jadi kami sengaja tidak menyalin perintahnya di sini agar tidak kedaluwarsa.

Verifikasi setelah terpasang:

injectived version
Alternatif kalau injectived sulit dipasang

Kalau instalasi bermasalah, kamu bisa memakai Docker image resmi Injective untuk menjalankan perintah injectived tanpa memasangnya di sistemmu. Tanya di grup Telegram โ€” beberapa peserta biasanya sudah menemukan jalur termudah untuk OS masing-masing.


๐Ÿ”‘ Step 4 โ€” Siapkan Keyโ€‹

Impor wallet-mu ke injectived. Pakai wallet latihan, bukan yang berisi aset sungguhan.

injectived keys add wallet-clc11 --recover

Perintah ini akan meminta seed phrase-mu.

Ini menaruh seed phrase-mu ke dalam keyring komputer

Pastikan ini adalah wallet latihan yang hanya berisi testnet INJ. Jangan pernah memasukkan seed phrase wallet utama ke CLI mana pun.

Kalau kamu belum punya wallet latihan terpisah, buat sekarang:

injectived keys add wallet-clc11

Perintah ini membuat wallet baru dan menampilkan seed phrase-nya. Catat di kertas, lalu ambil testnet INJ untuk alamat itu dari faucet.

Simpan alamatmu ke variabel supaya perintah berikutnya lebih ringkas:

export INJ_ADDRESS=$(injectived keys show wallet-clc11 -a)
echo $INJ_ADDRESS

Hasilnya harus dimulai dengan inj1....

Cek saldo:

injectived query bank balances $INJ_ADDRESS \
--node=https://testnet.sentry.tm.injective.network:443
Parameter testnet yang selalu dipakai

Setiap perintah injectived untuk testnet butuh dua flag ini:

  • --chain-id="injective-888" โ€” testnet (mainnet adalah injective-1)
  • --node=https://testnet.sentry.tm.injective.network:443

Perhatikan bahwa ini berbeda dari endpoint EVM di Jalur A. Sisi Cosmos dan sisi EVM punya endpoint sendiri-sendiri.


๐Ÿ“ค Step 5 โ€” Store Contractโ€‹

Unggah kode Wasm ke chain:

injectived tx wasm store artifacts/counter_injective.wasm \
--from=$INJ_ADDRESS \
--chain-id="injective-888" \
--yes --fees=1000000000000000inj --gas=2000000 \
--node=https://testnet.sentry.tm.injective.network:443

Sesuaikan nama file .wasm dengan hasil di folder artifacts/.

Perintah ini mengembalikan hash transaksi. Ambil code_id dari situ:

injectived query tx <TX_HASH> \
--node=https://testnet.sentry.tm.injective.network:443 \
--output json | grep -A1 code_id

Simpan nilainya:

export CODE_ID=<code_id_yang_kamu_dapat>
Testnet Injective permissionless

Siapa pun bisa store contract di testnet tanpa izin khusus. Di mainnet ada aturan tambahan โ€” tapi itu di luar cakupan camp ini.


๐Ÿ—๏ธ Step 6 โ€” Instantiateโ€‹

Sekarang buat instance dari code_id itu:

INIT='{"count":99}'

injectived tx wasm instantiate $CODE_ID $INIT \
--label="CounterCLC11" \
--from=$INJ_ADDRESS \
--chain-id="injective-888" \
--yes --fees=1000000000000000inj \
--gas=2000000 \
--no-admin \
--node=https://testnet.sentry.tm.injective.network:443

Perhatikan INIT โ€” ini adalah InstantiateMsg dari Unit 2 dalam bentuk JSON. Persis seperti yang kita bahas di sana.

Ambil alamat contract dari hasil transaksi, lalu simpan:

export CONTRACT=<alamat_inj1_hasil_instantiate>
Soal --no-admin

Flag ini berarti contract tidak bisa di-upgrade setelah dibuat. Untuk latihan ini aman dan sesuai konvensi dokumentasi resmi.

Kalau kamu menghilangkannya dan menetapkan admin, admin itu bisa mengganti kode contract kapan saja โ€” yang berarti pengguna harus mempercayai admin sepenuhnya. Ini keputusan desain penting saat membangun sesuatu yang sungguhan.


โ–ถ๏ธ Step 7 โ€” Executeโ€‹

Panggil increment:

INCREMENT='{"increment":{}}'

injectived tx wasm execute $CONTRACT "$INCREMENT" \
--from=$INJ_ADDRESS \
--chain-id="injective-888" \
--yes --fees=1000000000000000inj --gas=2000000 \
--node=https://testnet.sentry.tm.injective.network:443 \
--output json

Coba juga reset:

RESET='{"reset":{"count":42}}'

injectived tx wasm execute $CONTRACT "$RESET" \
--from=$INJ_ADDRESS \
--chain-id="injective-888" \
--yes --fees=1000000000000000inj --gas=2000000 \
--node=https://testnet.sentry.tm.injective.network:443 \
--output json

๐Ÿ” Step 8 โ€” Queryโ€‹

Query gratis dan tidak butuh tanda tangan:

GET_COUNT='{"get_count":{}}'

injectived query wasm contract-state smart $CONTRACT "$GET_COUNT" \
--node=https://testnet.sentry.tm.injective.network:443 \
--output json

Hasilnya kira-kira:

{"data":{"count":42}}

๐ŸŽ‰ Contract CosmWasm pertamamu berjalan di Injective testnet.


๐Ÿงช Latihan Verifikasiโ€‹

Buktikan bahwa kontrol aksesmu bekerja di chain sungguhan, bukan hanya di test:

  1. Buat wallet kedua: injectived keys add wallet-test2
  2. Kirim sedikit testnet INJ ke wallet itu untuk gas
  3. Coba panggil reset dari wallet kedua
  4. Transaksinya harus gagal dengan error Unauthorized
Kenapa latihan ini berharga

Test unit di Unit 2 berjalan di lingkungan simulasi. Latihan ini membuktikan bahwa perilaku yang sama benar-benar terjadi di chain sungguhan.

Kesenjangan antara "lolos di test" dan "benar di produksi" adalah tempat bug mahal bersembunyi. Membiasakan diri memverifikasi keduanya adalah kebiasaan profesional yang baik.


๐Ÿ› ๏ธ Troubleshootingโ€‹

Docker optimizer: "permission denied" atau "cannot connect to Docker daemon"

Docker belum berjalan. Jalankan Docker Desktop, atau di Linux:

sudo systemctl start docker

Kalau muncul masalah izin di Linux, tambahkan dirimu ke grup docker:

sudo usermod -aG docker $USER

Lalu logout dan login lagi.

"out of gas"

Naikkan nilai --gas. Coba --gas=3000000 atau lebih tinggi. Contract yang besar butuh lebih banyak gas untuk di-store.

"insufficient funds"

Saldo testnet INJ tidak cukup. Ambil lagi dari faucet, dan pastikan kamu meminta ke alamat inj1... yang benar โ€” cek dengan echo $INJ_ADDRESS.

"contract size exceeds limit"

Kamu men-deploy hasil cargo wasm yang belum dioptimasi. Jalankan Docker optimizer dan deploy file dari folder artifacts/, bukan dari target/.

"failed to execute message; message index: 0: Unauthorized"

Kontrol aksesmu bekerja. Kalau ini terjadi saat kamu memakai wallet pemilik, periksa --from menunjuk ke akun yang benar โ€” akun yang melakukan instantiate, bukan yang lain.

Perintah menggantung tanpa respons

Node publik kadang lambat atau sedang penuh. Tekan Ctrl+C dan coba lagi. Cek dulu apakah transaksinya sebenarnya sudah masuk sebelum mengulang โ€” kalau tidak, kamu bisa mengirim transaksi yang sama dua kali.


โœ… Checklistโ€‹

  • File .wasm teroptimasi ada di folder artifacts/
  • injectived terpasang dan injectived version berjalan
  • Key latihan terimpor, $INJ_ADDRESS berisi alamat inj1...
  • Ada testnet INJ di alamat itu
  • Contract ter-store, code_id tercatat
  • Contract ter-instantiate, alamat contract tercatat
  • increment berhasil, get_count menunjukkan nilai yang bertambah
  • Latihan verifikasi: wallet lain gagal memanggil reset
Simpan bukti untuk submission

Catat code_id, alamat contract, dan hash transaksi. Screenshot output terminal saat get_count berhasil.

Kumpulkan sekarang selagi masih segar โ€” panduan submission akan memintanya.


๐ŸŽฏ Rangkumanโ€‹

Yang Harus Kamu Ingat
  • Alur: cargo wasm โ†’ Docker optimizer โ†’ artifacts/*.wasm โ†’ store โ†’ instantiate โ†’ execute/query
  • Deploy dari folder artifacts/, bukan target/ โ€” kalau tidak, ukurannya akan ditolak
  • Testnet: --chain-id="injective-888", node https://testnet.sentry.tm.injective.network:443
  • Endpoint sisi Cosmos berbeda dari endpoint EVM di Jalur A
  • Store memberi code_id; instantiate memberi alamat contract. Satu code_id bisa banyak instance
  • --no-admin berarti contract tidak bisa di-upgrade โ€” keputusan kepercayaan yang penting
  • Query gratis, execute bayar gas
  • Verifikasi kontrol akses di chain sungguhan, bukan hanya di unit test

โœ… Quick Checkโ€‹

  1. Kenapa hasil cargo wasm tidak bisa langsung di-deploy?
  2. Apa beda code_id dan alamat contract?
  3. Apa chain-id testnet Injective untuk perintah injectived?
  4. Apa konsekuensi memakai --no-admin?
  5. Kenapa query tidak butuh flag --from dan --fees?

๐ŸŽ‰ Phase 2 selesai! Kamu sudah men-deploy contract di kedua VM Injective.

Ini mencakup Learning Track Phase 3, 4, dan 5 โ€” bagian tersulit dari track sudah lewat.

Lanjut: Phase 3 โ€” Setup Injective TypeScript SDK ๐Ÿ‘‰