Lewati ke konten

Menjalankan node OpenFiat

Operator node menjaga pasar terdesentralisasi yang berdiri di atas blockchain. Validator Solana mengamankan chain dan mengeksekusi program OpenFiat; node mengangkut daftar iklan, reputasi, pesan, dan penemuan.

Perintah di bawah menggunakan deployment rujukan: layanan openfiat-node, /etc/openfiat untuk konfigurasi, dan /var/lib/openfiat untuk data.

Perangkat keras

Minimum

4 core CPU · 16 GB RAM · SSD NVMe 250 GB · Koneksi broadband stabil

Direkomendasikan untuk produksi

8–16 core CPU · 32 GB RAM atau lebih · SSD NVMe 1 TB · Jaringan berbandwidth tinggi, berlatensi rendah · Perlindungan daya lewat UPS · Konektivitas internet redundan

Node adalah satu biner Rust tunggal. libp2p (QUIC, Noise, Yamux) dan RocksDB dikompilasi di dalamnya — tak ada yang perlu dipasang terpisah.

Di mana menjalankannya

AllenHark memimpin pengembangan awal protokol dan menjual dua hal yang dibutuhkan sebuah node: sebuah server dan akses RPC ke Solana. Operator node mendapat diskon 50% untuk keduanya, sebagai bagian dari program OpenFiat.

Hosting server

Penyimpanan NVMe pada tautan 10 Gbps, di Frankfurt, Amsterdam, dan Chicago. Sesuaikan ukuran dengan perangkat keras di atas — penyimpanan adalah hal yang lambat laun dituntut sebuah node penuh, jadi sebutkan apa yang Anda jalankan dan ia dapat dispesifikasikan untuk Anda.

Lihat harga

RPC & gRPC Solana

Koneksi ber-stake, agar transaksi yang dikirim node Anda tak mengantre di belakang milik semua orang. Akses diberikan melalui daftar IP yang diizinkan alih-alih kunci API. Yellowstone gRPC tersedia untuk men-streaming pembaruan akun dan slot.

Lihat harga

Mengklaim diskon

Tak ada kode untuk dimasukkan. Tanya di Discord atau di chat di allenhark.com, sebutkan bahwa Anda menjalankan node OpenFiat, dan diskon diterapkan ke pesanan Anda.

Layani jaringan, bukan hanya diri sendiri

Node yang hanya membaca adalah tamu. Node yang dapat dijangkau publik adalah infrastruktur — dompet, explorer, dan aplikasi web perlu berbicara dengan *seseorang*, dan hari ini seseorang semacam itu sedikit. Setiap operator yang menempatkan node-nya di balik TLS dan menyetel --public-rpc-url memperluas himpunan itu, yang menjadi perbedaan antara jaringan dengan banyak pintu masuk independen dan jaringan dengan satu titik kegagalan yang diam-diam diandalkan semua orang. Biayanya sebuah sertifikat dan sebuah reverse proxy. Ada imbalannya juga: node yang terjangkau adalah node yang dapat ditantang dan diberi imbalan oleh peer, dan aplikasi OpenFiat sendiri akan memakai node Anda bersama semua lainnya.

Dua hal yang perlu diketahui lebih dulu. Melayani publik berarti trafik nyata, jadi sesuaikan ukuran mesin untuk itu dan awasi endpoint metrik. Dan node publik adalah komitmen publik — orang akan membangun terhadap URL yang Anda terbitkan, jadi tarik ia secara sengaja alih-alih diam-diam.

Pemasangan

Bangun dari sumber — untuk produksi, hari ini

Belum ada versi yang ditandai, jadi saat ini inilah satu-satunya cara memperoleh biner node. Butuh toolchain Rust dan toolchain C untuk RocksDB. Bangun, letakkan di /usr/local/bin, dan jalankan di bawah systemd — inilah deployment yang didokumentasikan halaman ini, dan yang semestinya dipakai untuk node yang menjadi sandaran orang lain.

shell
# Rust toolchain, then build the node binary
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
apt install -y build-essential pkg-config libssl-dev clang cmake

git clone https://github.com/OpenFiat-org/openfiat-core.git
cd openfiat-core
cargo build --release --bin openfiat-node

install -m 0755 target/release/openfiat-node /usr/local/bin/

Biner prabangun — begitu ada versi yang ditandai

Mendorong sebuah tag v* menjalankan workflow rilis, yang membangun openfiat-node di runner native dan menerbitkan arsip linux-x86_64 dan windows-x86_64 di GitHub Releases. Belum ada yang ditandai, jadi halaman itu kosong untuk saat ini. Perhatikan ini adalah build rilis biasa, bukan statis maupun bertanda tangan — verifikasi yang Anda unduh terhadap workflow yang memproduksinya.

Rilis GitHub
shell
useradd --system --create-home --home-dir /var/lib/openfiat --shell /usr/sbin/nologin openfiat
install -m 755 openfiat-node /usr/local/bin/openfiat-node
mkdir -p /etc/openfiat
chown -R openfiat:openfiat /var/lib/openfiat

systemctl daemon-reload
systemctl enable --now openfiat-node
journalctl -u openfiat-node -f

Docker — hanya untuk pengujian

Gunakan image untuk mencoba sebuah node secara lokal atau menaikkan klaster multi-node sekali pakai — bukan untuk menjalankan node yang menjadi sandaran jaringan. Ia ada untuk pengujian lokal yang reprodusibel; produksi menjalankan biner di bawah systemd.

compose.yaml
# /opt/openfiat/compose.yaml
# TESTING ONLY. Use this to try a node locally or to bring up a throwaway
# cluster — run a production node from the binary under systemd instead
# (see the unit file further down this page).
services:
  node:
    image: ghcr.io/openfiat-org/openfiat-node:latest
    restart: unless-stopped
    # QUIC needs UDP; the same TCP port serves JSON-RPC, WebSocket, REST,
    # health, and metrics together — there is no separate metrics port.
    ports:
      - "4001:4001/udp"
      - "7080:7080/tcp"
    volumes:
      - /var/lib/openfiat:/data
      - /etc/openfiat/wallet.json:/data/wallet.json:ro
    command:
      - --ledger=/data
      - --identity=/data/wallet.json
      - --rpc-bind-address=0.0.0.0:7080
      - --gossip-bind-address=/ip4/0.0.0.0/udp/4001/quic-v1
      # Static multiaddr — DNS bootstrap does not resolve (see this
      # file's own top comment). Repeat the flag for several.
      - --entrypoint=/ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1
      # Omit to stay GossipOnly, the safe default. Any value opts into
      # real Solana devnet connectivity (OFS-4300 §4).
      - --solana-rpc-url=https://api.devnet.solana.com
    stop_grace_period: 60s
    ulimits:
      nofile: 65536
shell
install -d -m 0750 /var/lib/openfiat
docker compose -f /opt/openfiat/compose.yaml up -d
docker compose -f /opt/openfiat/compose.yaml logs -f node

Port

  • 4001/UDPTrafik antarpeer. QUIC adalah transport utama, jadi port UDP ini harus terjangkau — yang paling sering lupa dibuka orang.Harus terjangkau
  • 7080/TCPJSON-RPC, WebSocket, REST, health, dan metrik — satu port nyata melayani semuanya, tak ada port terpisah per permukaan.Harus terjangkau
  • 7080/TCPPort yang sama dengan API di atas (GET /metrics). Batasi dengan firewall ke loopback/jaringan privat jika Anda tak ingin ia publik.Jaga tetap privat

Menjadikan node daring

Kerjakan langkah-langkah ini secara berurutan. Tiap langkah di bawah membawa perintah yang dibutuhkannya.

  1. 01

    Siapkan mesin

    Sebuah server Debian atau Ubuntu mutakhir, sebuah firewall, dan jam yang akurat. Jam lebih penting dari yang terlihat: rekaman membawa timestamp dan waktu kedaluwarsa, dan jam yang bergeser membuat sebuah node menolak data yang valid.

    shell
    # Debian 12 / Ubuntu 24.04, as root
    apt update && apt install -y ca-certificates curl gnupg ufw chrony
    
    # Clock drift breaks signature and expiry checks — keep NTP running.
    systemctl enable --now chrony
  2. 02

    Pasang node

    Bangun dari sumber dan jalankan hasilnya di bawah systemd — belum ada versi yang ditandai, jadi inilah satu-satunya cara memperoleh biner hari ini, dan sisa manual ini mengasumsikannya. Gunakan Docker hanya saat menguji secara lokal atau menaikkan klaster sekali pakai.

  3. 03

    Bangkitkan dompet node

    Tak ada format «identitas node» terpisah — identitas sebuah node adalah wallet.json CLI Solana yang sebenarnya, file yang sama yang diproduksi solana-keygen. Seed-nya dipakai ulang baik untuk identitas gossip/peer node maupun kunci penandatanganan Solana. Simpan file itu — jika Anda kehilangannya, node bergabung kembali sebagai orang asing dan mulai membangun reputasi dari nol.

    shell
    # The node's identity IS a Solana CLI-format wallet.json — the same
    # file "solana-keygen new" produces (its own seed is reused for the
    # node's gossip/P2P keypair too, see crates/cli's load_or_generate_wallet).
    # There is no separate "node identity" format or command.
    solana-keygen new --outfile /etc/openfiat/wallet.json
    chmod 600 /etc/openfiat/wallet.json
    solana-keygen pubkey /etc/openfiat/wallet.json
  4. 04

    Setel lingkungan

    openfiat-node tak punya file konfigurasi sendiri — tiap pengaturan adalah variabel lingkungan, dibaca sekali saat startup: di mana data berada, alamat mana yang didengarkan, peer mana yang dihubungi saat mulai, dan (opsional) endpoint RPC Solana mana yang dipakai. Peer bootstrap harus berupa multiaddr/IP statis, bukan nama host — bootstrap DNS tak diresolusi.

    shell
    # There is no config file and no environment variables. Every
    # setting is a flag on the systemd unit's ExecStart below, so
    # "systemctl cat openfiat-node" shows exactly what a running node was
    # given, and "openfiat-node --help" is the whole surface.
    #
    # Try it in the foreground first — the node prints the addresses it is
    # reachable at and whether it reached Solana:
    
    openfiat-node \
      --ledger /var/lib/openfiat \
      --identity /etc/openfiat/wallet.json \
      --rpc-bind-address 0.0.0.0:7080 \
      --gossip-bind-address /ip4/0.0.0.0/udp/4001/quic-v1 \
      --entrypoint /ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1 \
      --solana-rpc-url https://api.devnet.solana.com
    
    # Omit --solana-rpc-url to stay GossipOnly, the safe default: the node
    # still serves the marketplace, but its on-chain answers come
    # second-hand from peers. Never put a real endpoint or API key anywhere
    # version controlled — it belongs in the unit file on the server.
    #
    # Add --ipfs-api-url http://127.0.0.1:5001 to pin protocol content and
    # earn the full reward share, and --retention archival to keep the whole
    # history instead of a rolling 30 days.
  5. 05

    Buka port yang tepat

    Peer menjangkau node lewat UDP karena QUIC adalah transport utama — itulah port yang paling sering dilupakan. Satu port TCP melayani JSON-RPC, WebSocket, REST, health, dan metrik bersama-sama; jaga tetap privat jika Anda tak ingin melayani klien secara publik.

    shell
    ufw default deny incoming
    ufw allow 22/tcp                 # keep your own access
    ufw allow 4001/udp               # libp2p, QUIC — the port people most often forget
    ufw allow 443/tcp                # once nginx terminates TLS in front (see below)
    ufw allow 7080/tcp               # only if the node is exposed directly, without a proxy
    ufw enable && ufw status verbose
  6. 06

    Layani jaringan: jadikan node Anda terjangkau

    Inilah langkah yang mengubah sebuah node dari sesuatu yang mengamati jaringan menjadi sesuatu yang mengangkutnya. Tempatkan nginx di depan dan peroleh sebuah sertifikat, lalu beri tahu node URL publiknya dengan --public-rpc-url dan ia mengumumkan dirinya agar dompet, explorer, dan aplikasi web OpenFiat sendiri dapat memakainya. Urutannya penting: nginx di atas HTTP polos dulu, lalu certbot menambahkan TLS — sebuah konfigurasi yang sudah menyebut sebuah sertifikat tak dapat memulai, sehingga certbot gagal sebelum sempat menerbitkan sertifikat yang akan menyelesaikannya. Sebuah sertifikat bukan hiasan opsional: sebuah halaman yang dilayani lewat HTTPS tak dapat membuka koneksi HTTP polos, jadi node tanpa sertifikat tak terlihat oleh setiap browser betapa pun sehatnya.

    /etc/nginx/sites-available/openfiat-node
    # /etc/nginx/sites-available/openfiat-node
    #
    # HTTP only at this stage, with NO TLS directives. certbot --nginx works
    # by running "nginx -t" and editing this file, so a config that already
    # points at a certificate cannot load, nginx will not start, and certbot
    # fails before it can issue the certificate that would have fixed it.
    server {
        listen 80;
        listen [::]:80;
        server_name openfiat.example.com;
    
        location / {
            proxy_pass http://127.0.0.1:7080;
            proxy_http_version 1.1;
    
            # The node serves its WebSocket event stream on the same port;
            # without these the stream downgrades to a plain request and
            # subscriptions silently never deliver.
            proxy_set_header Upgrade    $http_upgrade;
            proxy_set_header Connection "upgrade";
    
            proxy_set_header Host              $host;
            proxy_set_header X-Real-IP         $remote_addr;
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
    
            # Do NOT add CORS headers here — the node already sets them, and
            # two Access-Control-Allow-Origin headers on one response make
            # browsers reject it while curl sees a clean 200.
            proxy_read_timeout 300s;
        }
    }
    shell
    # The A record must already resolve for the world — certbot proves
    # control of the name over port 80. Check a public resolver, not your
    # own machine, whose cache can be stale:
    dig +short @8.8.8.8 openfiat.example.com
    
    ln -s /etc/nginx/sites-available/openfiat-node /etc/nginx/sites-enabled/
    nginx -t && systemctl reload nginx
    curl -s http://openfiat.example.com/health    # ok, before any certificate
    
    apt install -y certbot python3-certbot-nginx
    certbot --nginx -d openfiat.example.com
    
    # certbot edits the server block in place: it adds listen 443 ssl, the
    # certificate paths, and a redirect from :80. The location block and its
    # proxy headers carry over. Renewal installs itself as a systemd timer.
    # Do not hand-write a 443 block afterwards — certbot manages that one.
    
    # Then tell the network this node can be reached directly:
    #   openfiat-node --public-rpc-url https://openfiat.example.com
  7. 07

    Jalankan sebagai layanan

    Di bawah systemd node memulai ulang setelah crash atau reboot, dan memperoleh periode mati yang cukup panjang agar basis data mengosong dengan bersih alih-alih dibunuh di tengah sebuah penulisan.

    openfiat-node.service
    # /etc/systemd/system/openfiat-node.service
    [Unit]
    Description=OpenFiat node
    Documentation=https://docs.openfiat.network
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=openfiat
    Group=openfiat
    ExecStart=/usr/local/bin/openfiat-node \
        --ledger /var/lib/openfiat \
        --identity /etc/openfiat/wallet.json \
        --rpc-bind-address 0.0.0.0:7080 \
        --gossip-bind-address /ip4/0.0.0.0/udp/4001/quic-v1 \
        --entrypoint /ip4/84.32.223.111/udp/4001/quic-v1/p2p/12D3KooWK9hQ7TwbfvFiaAxUbRFCkdhS7iEpAJDnewNL1anyREQ1 \
        --solana-rpc-url https://api.devnet.solana.com
    WorkingDirectory=/var/lib/openfiat
    Restart=on-failure
    RestartSec=5s
    
    # openfiat-node handles SIGTERM itself (graceful shutdown) rather than
    # needing systemd to force-kill it; this gives that shutdown path a
    # reasonable window before systemd escalates to SIGKILL.
    TimeoutStopSec=30s
    
    NoNewPrivileges=true
    ProtectSystem=strict
    ProtectHome=true
    ReadWritePaths=/var/lib/openfiat
    PrivateTmp=true
    
    # AF_NETLINK is required, not optional: binding a wildcard address makes
    # libp2p enumerate this host's interfaces, and that goes over a netlink
    # socket. Without it the QUIC listener fails and the gossip actor panics
    # while the HTTP thread survives — so systemd reports the unit active
    # and the node looks healthy while serving nothing.
    RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
    
    [Install]
    WantedBy=multi-user.target
    shell
    useradd --system --create-home --home-dir /var/lib/openfiat --shell /usr/sbin/nologin openfiat
    install -m 755 openfiat-node /usr/local/bin/openfiat-node
    mkdir -p /etc/openfiat
    chown -R openfiat:openfiat /var/lib/openfiat
    
    systemctl daemon-reload
    systemctl enable --now openfiat-node
    journalctl -u openfiat-node -f
  8. 08

    Biarkan ia menyusul

    Alih-alih memutar ulang seluruh riwayat, sebuah node baru dapat menemukan dan mengimpor snapshot keadaan pasar saat ini yang diumumkan peer (OFS-1300) — metode JSON-RPC yang sebenarnya, bukan perkakas terpisah: getLatestSnapshot, getCheckpointHeight. Tanda tangan, versi protokol, dan state root, semua harus cocok sebelum dipercaya.

    shell
    # Snapshot sync (OFS-1300) is real JSON-RPC, not a separate CLI —
    # a new node discovers and imports a peer-announced snapshot instead of
    # replaying all history:
    curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \
      -d '{"jsonrpc":"2.0","id":1,"method":"getLatestSnapshot","params":{}}'
    curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \
      -d '{"jsonrpc":"2.0","id":1,"method":"getCheckpointHeight","params":{}}'
  9. 09

    Verifikasi ia sehat

    GET /health menegaskan proses berjalan; getChainStatus lewat JSON-RPC menyatakan apakah ia GossipOnly atau RpcConnected, dan blockhash-nya saat ini jika itu yang terbaru.

    shell
    # Is it up, and which mode is it in?
    curl -s http://localhost:7080/health
    # ok
    
    curl -s -X POST http://localhost:7080/rpc -H 'content-type: application/json' \
      -d '{"jsonrpc":"2.0","id":1,"method":"getChainStatus","params":{}}'
    # {"jsonrpc":"2.0","id":1,"result":{"mode":"GossipOnly","blockhash":null,"slot":null,"age_ms":null}}
    # ("RpcConnected" with a real blockhash once --solana-rpc-url is set)
    
    # The addresses your node is reachable at are in its own log — give one
    # of these to another operator as their --entrypoint:
    journalctl -u openfiat-node | grep "reachable at a new address"
  10. 10

    Ia sudah bagian dari jaringan

    Tak ada langkah «mengumumkan» terpisah — begitu sebuah node punya peer bootstrap, ia mem-gossip dan disebarkan otomatis; tak ada yang menyetujuinya. Men-stake, menerbitkan metadata di registri layanan, mengikuti sengketa, dan memberikan suara tata kelola adalah tindakan terpisah, dipandu dompet, yang dilakukan sebuah klien terhadap node yang berjalan — lihat panduan partisipasi terkait untuk masing-masing.

    Sebuah node men-stake OPEN untuk menjadi peserta aktif. Namun stake tak membeli reputasi: operator berkinerja buruk tak dapat menutupinya dengan men-stake lebih banyak. Prioritas efektif memadukan reputasi, stake, dan kinerja jaringan yang terukur.

  11. 11

    Awasi ia

    Sinyal yang benar-benar memprediksi masalah adalah peer yang terhubung, mode chain (GossipOnly vs RpcConnected), dan umur blockhash. Setel peringatan pada itu dan Anda akan tahu sebelum pengguna Anda.

    prometheus.yml
    # /etc/prometheus/prometheus.yml — same port as everything else,
    # no separate metrics listener to configure on the node's own side.
    scrape_configs:
      - job_name: openfiat-node
        static_configs:
          - targets: ["127.0.0.1:7080"]
  12. 12

    Jaga tetap mutakhir

    Hentikan, tukar biner, mulai. Node memperbarui satu per satu, jadi jaringan tak pernah butuh penghentian terkoordinasi, dan peristiwa gossip yang terlewat diputar ulang saat startup.

    shell
    systemctl stop openfiat-node        # SIGTERM, lets RocksDB flush
    # docker: docker compose pull node && docker compose up -d node
    install -m 0755 ./openfiat-node /usr/local/bin/
    systemctl start openfiat-node
    
    # Missed gossip events replay automatically on start.
    journalctl -u openfiat-node -f
  13. 13

    Cadangkan yang tak dapat dibangkitkan kembali

    Keadaan pasar selalu dapat disinkronkan ulang dari sebuah snapshot. Dompet tak dapat dibangkitkan kembali. Saldo dan kustodi berada di Solana, bukan di disk Anda.

    shell
    # Back up what cannot be re-derived. Marketplace state can always be
    # re-synced from a snapshot; the wallet cannot be regenerated.
    tar czf openfiat-wallet-$(date +%F).tar.gz /etc/openfiat/wallet.json
    
    # Authoritative financial state lives on Solana, not on the node's own
    # RocksDB volume.

Saat ada yang salah

Tak ada peer yang terhubung

UDP 4001 terblokir, atau --entrypoint menunjuk ke alamat yang sebenarnya tak dapat dijangkau peer — ia harus berupa multiaddr/IP statis, bukan nama host (bootstrap DNS tak diresolusi). Node Anda sendiri mencatat alamat tempat ia terjangkau begitu ia mendengarkan.

shell
ss -lunp | grep 4001 && journalctl -u openfiat-node -n 100

Sinkronisasi tak pernah selesai

Impor snapshot (OFS-1300) belum tuntas, atau belum ada peer yang mengumumkan snapshot yang cukup baru — periksa getLatestSnapshot/getCheckpointHeight.

shell
journalctl -u openfiat-node -n 200 --no-pager | grep -i snapshot

Penggunaan disk terus bertambah

RocksDB belum melakukan kompaksi.

shell
du -sh /var/lib/openfiat/*

Tanda tangan atau kedaluwarsa ditolak

Pergeseran jam. Rekaman membawa timestamp dan kedaluwarsa, jadi jam host harus benar.

shell
chronyc tracking

Apa yang harus diekspos sebuah node

Itulah semua yang diekspor node hari ini — jumlah peer, mode chain, dan kemajuan sinkronisasi belum menjadi metrik Prometheus, hanya nilai yang dapat Anda kueri lewat JSON-RPC (getChainStatus, getLatestSnapshot, getCheckpointHeight).

Infrastruktur

CPU · Memori · Disk · Throughput jaringan

Protokol (GET /metrics)

rpc_requests_total · rpc_errors_total

Menghosting antarmuka pengguna

OpenFiat memisahkan protokol dari antarmukanya. Siapa pun dapat menghosting antarmuka web, gateway seluler, portal korporat, atau pasar regional, dan masing-masing menjangkau pasar yang sama.

Apa pun antarmuka yang digunakan, setiap peserta berinteraksi dengan pasar terdesentralisasi yang sama.

Antarmuka web resmi · Antarmuka komunitas · Antarmuka merchant · Pasar regional · Portal korporat

Ke mana sebuah antarmuka terhubung

Antarmuka tak berbicara langsung dengan chain. Mereka terhubung ke satu atau lebih node OpenFiat terdekat, dan beralih ke node lain jika satu menjadi tak tersedia.

Permukaan API node

  • PasarMengambil iklan · Membuat iklan · Memperbarui iklan · Menghapus iklan
  • TransaksiMemesan iklan · Menyinkronkan sesi transaksi · Mengirim konfirmasi pembayaran
  • InfrastrukturPenemuan peer · Penemuan gateway · Informasi snapshot · Intelijen risiko
  • Tata kelolaPenemuan proposal · Pengiriman suara · Informasi treasury

Setiap node yang patuh mengekspos permukaan API yang sama, sehingga antarmuka yang ditulis terhadap satu node bekerja terhadap semuanya.

Node tak pernah mengkustodi dana pengguna. Semua operasi finansial tetap di bawah kendali smart contract Solana.