Ми — команда блокчейн-інженерів з 7-річним досвідом у Web3. За останні три роки ми розгорнули понад 15 смарт-контрактів у parachain Astar та Kusama. Коли клієнт приходить з задачею перенести свій DeFi-протокол з Ethereum у Polkadot, перше, що ми пояснюємо: Polkadot — це не ще один L2. Тут немає єдиної VM для всіх мереж. Смарт-контракти деплояться не в Relay Chain, а в парачейни з включеним модулем pallet-contracts. Kusama — це канаркова мережа Polkadot з більш швидким governance та менш суворими вимогами до слотів. Для тестування production-логіки ми використовуємо Kusama, для фінального деплою — Polkadot або спеціалізований парачейн (Astar, Phala, Aleph Zero).
Нещодавно ми розгорнули vault-контракт для стейкінгу на Astar. Клієнт заощадив 40% на gas порівняно з EVM-версією — ink! контракти в середньому в 1.8 рази ефективніші за газом, ніж аналогічні Solidity на Moonbeam. Це досягається за рахунок компіляції в Wasm та більш точної моделі газу WeightV2.
Чому ink! а не Solidity для Polkadot?
Контракти для pallet-contracts пишуться на ink! — це нативний Rust з макросами, які генерують метадані контракту та ABI-сумісний інтерфейс. На відміну від Solidity, ink! дає прямий доступ до низькорівневих оптимізацій Rust і компілюється в Wasm.
#[ink::contract] mod vault { use ink::storage::Mapping; #[ink(storage)] pub struct Vault { balances: Mapping<AccountId, Balance>, owner: AccountId, } impl Vault { #[ink(constructor)] pub fn new() -> Self { Self { balances: Mapping::default(), owner: Self::env().caller(), } } #[ink(message, payable)] pub fn deposit(&mut self) { let caller = self.env().caller(); let value = self.env().transferred_value(); let current = self.balances.get(caller).unwrap_or(0); self.balances.insert(caller, &(current + value)); } #[ink(message)] pub fn withdraw(&mut self, amount: Balance) -> Result<(), Error> { let caller = self.env().caller(); let balance = self.balances.get(caller).unwrap_or(0); if balance < amount { return Err(Error::InsufficientBalance); } self.balances.insert(caller, &(balance - amount)); self.env().transfer(caller, amount) .map_err(|_| Error::TransferFailed) } } } Кілька ключових відмінностей від Solidity, які ламають інтуїцію EVM-розробника:
- Немає
msg.valueу звичайних функціях — тільки в#[ink(message, payable)]. Виклик payable-функції без прапорця поверне помилку. - Storage через
Mappingбез ітерації — немаєmapping.keys(). Якщо потрібні списки — зберігайте окремоVec<AccountId>. -
AccountIdзамістьaddress— 32 байти, не 20. Адреси у форматі SS58, не hex. -
Balanceцеu128, неuint256. Але практично різниці немає.
Як вибрати парачейн для деплою?
Не всі парачейни Polkadot підтримують смарт-контракти безпосередньо. Для ink! контрактів потрібні парачейни з включеним pallet-contracts. Нижче — порівняння популярних варіантів:
| Парачейн | Тип | Підтримка ink! | Особливості |
|---|---|---|---|
| Astar | Wasm+EVM | Так | Найбільша екосистема, cross-VM виклики через XVM |
| Phala | Wasm | Так | Конфіденційні контракти через TEE |
| Aleph Zero | Wasm+EVM | Так | Висока пропускна здатність, NFT-маркетплейси |
| Rococo (testnet) | testnet | Так | Безкоштовний faucet, ідеально для тестування |
Для production-деплою ми рекомендуємо Astar — він найбільш зрілий, має підтримку як Wasm, так і EVM, та багату інфраструктуру.
Інструментарій: cargo-contract
cargo install cargo-contract --force cargo contract new my_contract cd my_contract # Збірка: генерує .contract, .wasm, .json (ABI) cargo contract build --release # Запуск тестів cargo test Файл .contract — це архів з WASM bytecode та метаданими. Саме його деплоїмо.
Середовища деплою та тестування
Локальне тестування: substrate-contracts-node
substrate-contracts-node --dev --tmp Запускає однонодову мережу з попередньо фінансованими акаунтами (Alice, Bob, Charlie — як Hardhat accounts[0]). Contracts UI на contracts-ui.substrate.io або programmatic через @polkadot/api.
Тестнет: Contracts on Rococo
Rococo — тестнет Polkadot з парачейном contracts спеціально для тестування ink!. Faucet: paritytech.github.io/polkadot-testnet-faucet.
Production: Astar Network
Astar — найбільш зрілий парачейн з pallet-contracts у Polkadot ecosystem. Підтримує і ink! (Wasm), і EVM (Solidity) контракти в одній мережі, cross-VM виклики через XVM. Для більшості production use cases на Polkadot — деплоїмо на Astar.
Деплой через polkadot.js
import { ApiPromise, WsProvider, Keyring } from '@polkadot/api'; import { CodePromise } from '@polkadot/api-contract'; import * as fs from 'fs'; async function deploy() { const provider = new WsProvider('wss://rpc.astar.network'); const api = await ApiPromise.create({ provider }); const keyring = new Keyring({ type: 'sr25519' }); const deployer = keyring.addFromUri(process.env.MNEMONIC!); const wasm = fs.readFileSync('./target/ink/vault.wasm'); const abi = JSON.parse(fs.readFileSync('./target/ink/vault.json', 'utf8')); const code = new CodePromise(api, abi, wasm); const gasLimit = api.registry.createType('WeightV2', { refTime: 30_000_000_000n, proofSize: 1_000_000n, }); const storageDepositLimit = null; // автоматично const tx = code.tx.new({ gasLimit, storageDepositLimit }); await new Promise<void>((resolve, reject) => { tx.signAndSend(deployer, ({ contract, status }) => { if (status.isInBlock) { console.log('Contract address:', contract?.address.toString()); resolve(); } }).catch(reject); }); await api.disconnect(); } Модель газу: WeightV2
На відміну від EVM де gas — одне число, Substrate використовує двовимірний weight:
-
refTime— час обчислень (пікосекунди) -
proofSize— розмір storage proof для light clients
При деплої потрібно оцінити обидва параметри. Спосіб: сухий прогін (contracts.instantiate з estimateGas: true) або використовуємо cargo-contract:
cargo contract instantiate --dry-run \ --constructor new \ --args \ --suri //Alice \ --url ws://127.0.0.1:9944 Storage deposit
pallet-contracts вимагає депозит за зайнятий storage — аналог EIP-1153 transient storage, але постійний. Вартість пропорційна байтам у storage контракту. При видаленні storage (через ink::env::set_contract_storage::<K, ()>(&key, &())) депозит повертається. Це важливо для long-lived контрактів з великим state. На практиці storage deposit для типового контракту становить 0.1–0.5% від вартості деплою, що значно нижче, ніж на EVM-парачейнах.
Типові помилки при міграції з EVM
| EVM паттерн | ink! рішення |
|---|---|
mapping.length() |
Окремий лічильник або Vec |
block.timestamp |
self.env().block_timestamp() (u64, мілісекунди) |
msg.sender |
self.env().caller() |
payable за замовчуванням |
Явний атрибут #[ink(message, payable)] |
Events з indexed |
#[ink(topic)] на полі події |
require(cond, "msg") |
assert! або Result<_, Error> |
Cross-contract виклики в ink! вимагають імпорту ABI викликаного контракту та явного вказання gas ліміту — немає автоматичного forwarding як в Solidity {gas: gasleft()}.
Етапи деплою
- Аналіз вимог — вивчаємо логіку контракту, вибираємо парачейн.
- Написання контракту — реалізація на ink! з урахуванням безпеки та оптимізації газу.
- Тестування — локальне (substrate-contracts-node) та на Rococo.
- Аудит безпеки — зв'язка Slither для ink! та ручний аудит.
- Деплой у production — розгортання в Astar або іншому парачейні.
- Підтримка — моніторинг, оновлення, допомога користувачам.
Що входить у роботу
- Повний цикл від ідеї до деплою.
- Вихідний код з детальними коментарями.
- Документація по контракту (white paper, технічна специфікація).
- Тестовий звіт (результати unit-тестів та фаззингу).
- Доступи до контракту та інструкція по взаємодії.
- Місяць технічної підтримки після деплою.
Детальний чек-лист перед деплоєм
- Парачейн обрано (Astar/Phala/Aleph Zero)
- Контракт зібрано (
cargo contract build --release) - Пройдено unit-тести (
cargo test) - Пройдено фаззинг (Echidna або custom)
- Оцінено weight:
cargo contract instantiate --dry-run - Storage deposit розраховано та поповнено
- Тест на Rococo пройдено
- Акаунт deployer має достатньо коштів для деплою
Наша команда — сертифіковані спеціалісти Parity Substrate з 5+ роками досвіду в Rust та блокчейн-розробці. Ми гарантуємо результат: 15+ успішних деплоїв у Kusama та Polkadot. Докладніше про Substrate smart contracts читайте в офіційній документації.
Зв'яжіться з нами для оцінки вашого проекту. Замовте деплой під ключ — ми проведемо весь цикл від аналізу до підтримки. Оцінимо проект безкоштовно і назвемо точні терміни (від 2 тижнів до 2 місяців залежно від складності).







