Для чего нужна данная статья? :
Создать простую ноду адаптера и смарт-контракт. Интегрировать Substrate + Rust для SaaS-системы с поддержкой смарт-контрактов (Ink!), используя Actix Web API для взаимодействия с блокчейном:
- Substrate-нода (с поддержкой pallet-contracts для Ink!)
- API-сервис на Actix Web для вызова смарт-контрактов
- Смарт-контракт на Ink!
- Деплой и тестирование
Зачем Вам это уметь? :
1. DevOps и инфраструктурные сервисы
- CI/CD SaaS — альтернатива GitHub Actions, CircleCI, GitLab CI.
- Observability SaaS — логирование (типа Datadog, New Relic), мониторинг метрик (Prometheus, Grafana Cloud).
- Serverless & FaaS — аналог AWS Lambda (Fermyon Spin, OpenFaaS).
- Reverse Proxy & API Gateway SaaS — высокопроизводительный балансировщик (аналог Cloudflare Workers, API Gateway).
- Security SaaS — сканирование уязвимостей (аналог Snyk, Dependabot).
- Backup & Storage SaaS — облачное хранилище данных (аналог Backblaze, S3).
2. AI & ML SaaS
- LLM API SaaS — аналог OpenAI API, DeepSeek API, Mistral API.
- Vector Search SaaS — база векторных эмбеддингов (аналог Pinecone, Weaviate).
- AutoML SaaS — сервис для автоматического обучения моделей.
- GPU Acceleration SaaS — удалённые GPU-серверы (аналог RunPod, Lambda Labs).
3. FinTech & Crypto SaaS
- High-Frequency Trading (HFT) SaaS — низколатентная торговля на биржах.
- Crypto Wallet SaaS — мультикошелёк с API (аналог Fireblocks).
- DeFi SaaS — платформа управления DeFi-проектами.
- NFT Marketplace SaaS — аналог OpenSea API, Magic Eden API.
- Blockchain Indexer SaaS — API для быстрого доступа к блокчейну (аналог The Graph, Alchemy).
4. Web & API SaaS
- Headless CMS SaaS — аналог Strapi, Contentful.
- Authentication SaaS — аналог Auth0, Clerk, Supabase Auth.
- Feature Flags & A/B Testing SaaS — аналог LaunchDarkly, Split.io.
- Web Scraping SaaS — облачный парсинг данных (аналог ScraperAPI, Bright Data).
- WebRTC & Video Streaming SaaS — видеостриминг (аналог Twilio Video, Agora, LiveKit).
- API Rate Limiting SaaS — контроль нагрузки API (аналог Cloudflare Rate Limiting).
5. Cybersecurity & Privacy SaaS
- Zero Trust SaaS — защита корпоративных сетей (аналог Tailscale, Cloudflare Zero Trust).
- DDoS Protection SaaS — анти-DDoS защита (аналог Cloudflare, AWS Shield).
- Anonymity Proxy/VPN SaaS — аналог ProtonVPN API, Mullvad API.
- IAM & RBAC SaaS — управление доступами (аналог Okta, Keycloak).
- Password Manager SaaS — аналог Bitwarden, 1Password.
6. E-commerce & Payments SaaS
- Subscription Billing SaaS — аналог Stripe Billing, Paddle.
- Fraud Detection SaaS — защита платежей от мошенников.
- Headless E-commerce SaaS — аналог Shopify API, Medusa.
- Checkout & Payment Gateway SaaS — кастомный процессинг платежей.
7. Data & Analytics SaaS
- Big Data Processing SaaS — аналог Snowflake, Redshift.
- ETL/ELT SaaS — сервис для обработки данных (аналог Airbyte, Fivetran).
- Data Warehousing SaaS — облачные базы данных (аналог ClickHouse Cloud, BigQuery).
- BI & Dashboards SaaS — визуализация данных (аналог Metabase, Superset).
8. Developer Tools SaaS
- Code Collaboration SaaS — аналог GitHub Codespaces, CodeSandbox.
- Code Search SaaS — поиск кода по репозиториям (аналог Sourcegraph).
- Cloud IDE SaaS — аналог Replit, JetBrains Space.
- Static Analysis SaaS — анализ кода на уязвимости.
- Error Tracking SaaS — аналог Sentry, Rollbar.
9. Entertainment & Media SaaS
- Game Server Hosting SaaS — аналог PlayFab, Unity Multiplay.
- Music Streaming SaaS — аналог SoundCloud API, Audius.
- Video Transcoding SaaS — аналог Mux, Zencoder.
- Digital Asset Management SaaS — облачные медиа-хранилища.
10. Productivity & Collaboration SaaS
- Document Editing SaaS — аналог Google Docs, Notion.
- Task Management SaaS — аналог Trello, Asana.
- Video Conferencing SaaS — аналог Zoom API, Jitsi Meet.
- Chat & Messaging SaaS — аналог Twilio Chat, Slack API.
_______________________________
Сначала необходимо установить Substrate:
curl https://getsubstrate.io -sSf | bash
Настройка шаблона
git clone https://github.com/substrate-developer-hub/substrate-node-template
cd substrate-node-template
cargo build --release
Добавление поддержки смарт-контрактов runtime/Cargo.toml
[dependencies.pallet-contracts]
default-features = false
version = '4.0.0'
Добавление runtime/src/lib.rs
pub use pallet_contracts;
impl pallet_contracts::Config for Runtime {
type Time = Timestamp;
type Randomness = RandomnessCollectiveFlip;
type Currency = Balances;
type Event = Event;
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Runtime>;
type ChainExtension = ();
}
Сборка и запуск ноды
cargo build --release
./target/release/node-template --dev
✅ Теперь у нас есть локальная нода Substrate с поддержкой Ink!
Создание API
cargo new crypto-saas
cd crypto-saas
Cargo.toml:
[dependencies]
actix-web = "4.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
substrate-api-client = { git = "https://github.com/scs/substrate-api-client.git" }
tokio = { version = "1", features = ["full"] }
src/main.rs REST API для взаимодействия с контроллером:
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use serde::{Deserialize, Serialize};
use substrate_api_client::{Api, XtStatus};
use sp_keyring::AccountKeyring;
#[derive(Serialize, Deserialize)]
struct ContractCall {
contract_address: String,
method: String,
params: Vec<String>,
}
async fn call_contract(call: web::Json<ContractCall>) -> impl Responder {
let api = Api::new("ws://127.0.0.1:9944").set_signer(AccountKeyring::Alice.pair());
let contract_address = &call.contract_address;
let method = &call.method;
let params = &call.params;
// Пример вызова смарт-контракта
// Здесь предполагается наличие метода для взаимодействия с контрактом
let call_data = api.contract_call(contract_address, method, params).await;
match call_data {
Ok(result) => HttpResponse::Ok().json(result),
Err(_) => HttpResponse::InternalServerError().finish(),
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/call_contract", web::post().to(call_contract))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
✅ Теперь у нас есть REST API, которое взаимодействует с Substrate-нодой через WebSocket (ws://127.0.0.1:9944).
Развертывание смарт-контрактов на языке Ink!
#![cfg_attr(not(feature = "std"), no_std)]
#[ink::contract]
mod my_contract {
#[ink(storage)]
pub struct MyContract {
value: u32,
}
impl MyContract {
#[ink(constructor)]
pub fn new(init_value: u32) -> Self {
Self { value: init_value }
}
#[ink(message)]
pub fn get_value(&self) -> u32 {
self.value
}
#[ink(message)]
pub fn set_value(&mut self, new_value: u32) {
self.value = new_value;
}
}
}
Разворачиваем контракт
cargo contract deploy --url ws://127.0.0.1:9944
🔹 1. gRPC API Gateway (Actix Web + Tonic)
📂 Файл api_gateway.rs
use actix_web::{web, App, HttpServer, Responder};
use tonic::transport::Channel;
use prost::Message;
use crate::grpc::adapter_client::AdapterClient;
use crate::grpc::ProcessRequest;
mod grpc {
tonic::include_proto!("adapter");
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let grpc_client = AdapterClient::connect("http://127.0.0.1:50051").await.unwrap();
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(grpc_client.clone()))
.route("/process", web::get().to(process_request))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
async fn process_request(client: web::Data<AdapterClient<Channel>>) -> impl Responder {
let request = ProcessRequest {
data: "example data".into(),
};
let response = client.process(request).await;
match response {
Ok(res) => format!("Processed: {:?}", res.into_inner().result),
Err(err) => format!("Error: {:?}", err),
}
}
📌 Что делает код?
- Запускает HTTP API, который вызывает gRPC адаптер.
- Использует Tonic (gRPC) для общения с нода адаптера.
- Работает через Actix Web для обработки HTTP-запросов.
🔹 2. gRPC Адаптер с RabbitMQ/NATS
📂 Файл adapter.rs
use tonic::{transport::Server, Request, Response, Status};
use async_nats::{Client as NatsClient, connect};
use redis::{AsyncCommands, Client as RedisClient};
use sqlx::PgPool;
use s3::bucket::Bucket;
use prost::Message;
pub mod grpc {
tonic::include_proto!("adapter");
}
use grpc::adapter_server::{Adapter, AdapterServer};
use grpc::{ProcessRequest, ProcessResponse};
#[derive(Debug, Default)]
pub struct AdapterService {
pub db: PgPool,
pub redis: RedisClient,
pub s3: Bucket,
pub nats: NatsClient,
}
#[tonic::async_trait]
impl Adapter for AdapterService {
async fn process(&self, request: Request<ProcessRequest>) -> Result<Response<ProcessResponse>, Status> {
let data = request.into_inner().data;
// Кешируем в Redis
let mut conn = self.redis.get_async_connection().await.unwrap();
conn.set("last_request", &data).await.unwrap();
// Отправляем сообщение в NATS
self.nats.publish("processing", data.clone().into()).await.unwrap();
// Логируем в PostgreSQL
sqlx::query!("INSERT INTO logs (message) VALUES ($1)", data)
.execute(&self.db)
.await
.unwrap();
// Отправляем ответ
let response = ProcessResponse {
result: format!("Processed: {}", data),
};
Ok(Response::new(response))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = PgPool::connect("postgres://user:password@localhost/db").await?;
let redis = RedisClient::open("redis://127.0.0.1/")?;
let s3 = Bucket::new("my-bucket", s3::Region::UsEast1, s3::creds::Credentials::default()?)?;
let nats = connect("127.0.0.1:4222").await?;
let service = AdapterService { db, redis, s3, nats };
Server::builder()
.add_service(AdapterServer::new(service))
.serve("[::1]:50051".parse().unwrap())
.await?;
Ok(())
}
📌 Что делает код?
- Принимает gRPC-запрос с данными.
- Кеширует в Redis.
- Отправляет сообщение в NATS.
- Логирует в PostgreSQL.
- Хранит файлы в S3 (MinIO).
🔹 3. Смарт-контракт на Rust (Solana)
📂 Файл contract.rs
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
pubkey::Pubkey,
msg,
};
entrypoint!(process_instruction);
fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let accounts_iter = &mut accounts.iter();
let account = next_account_info(accounts_iter)?;
msg!("Executing smart contract logic...");
Ok(())
}
📌 Что делает код?
- Минимальный контракт для обработки вызовов.
- Взаимодействует с Solana для децентрализованных операций.
🔹 4. Observability (Jaeger, Prometheus, OpenTelemetry)
📂 Файл observability.rs
use opentelemetry::{global, sdk::trace::Tracer};
use opentelemetry_jaeger::PipelineBuilder;
use tracing::{info, span, Level};
use tracing_subscriber::Registry;
fn init_tracing() {
let tracer = PipelineBuilder::default().install_simple().unwrap();
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let subscriber = Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber).unwrap();
}
fn main() {
init_tracing();
let span = span!(Level::INFO, "processing_request");
let _guard = span.enter();
info!("Processing started...");
}
📌 Что делает код?
- OpenTelemetry для сбора метрик.
- Jaeger для трассировки.
- Prometheus для мониторинга.