Oasis esitles raamistikku runtime off-chain logika (ROFL) jaoks, mis aitab rakendusi väljaspool ahelat ehitada ja käitada, tagades samal ajal privaatsuse ning säilitades usalduse plokiahelas.Oasis esitles raamistikku runtime off-chain logika (ROFL) jaoks, mis aitab rakendusi väljaspool ahelat ehitada ja käitada, tagades samal ajal privaatsuse ning säilitades usalduse plokiahelas.

Juhtnöörid ristaheliste võtmete loomiseks (EVM / Base) koos Oasis ROFL-iga Oasis ROFL on uus ja põnev lahendus, mis võimaldab kasutajatel luua turvalisi ja hõlpsasti juurdepääsetavaid ristahelisi võtmeid. See pakub nii EVM-kettade kui ka Base-kettade kasutajatele suurepärast võimalust oma krüptovara turvaliselt hallata, ühendades samal ajal tugeva turvalisuse ja kasutajasõbraliku kasutuskogemuse.

Mis on ristahelised võtmed?

Ristahelised võtmed on krüptograafilised võtmed, mis võimaldavad kasutajatel juurdepääsu mitmele erinevale blockchainile ühe ja sama võtmega. Näiteks saate oma Ethereumi võtme kasutada nii Ethereumi kui ka Base-kettadel, vältides seeläbi keerukaid ja aeganõudvaid tegevusi, nagu võtmete importimine või eksportimine.

Kuidas Oasis ROFL töötab?

Oasis ROFL kasutab unikaalset arhitektuuri, mis tagab võtmete turvalisuse ja lihtsa juurdepääsu. Selle süsteemi abil saate luua võtmeid, mis on kaitstud nii privaatse võtme kui ka avaliku võtme eesmärgil. Lisaks pakub Oasis ROFL ka tugevat integreerimist teiste populaarsete blockchainidega, sealhulgas Ethereum, Polygon ja Base.

Samm-sammult: ristaheliste võtmete loomine

  1. Installige Oasis ROFL – Laadige alla ja installige Oasis ROFL rakendus oma seadmesse.
  2. Looge võti – Valige soovitud blockchain ja looge turvaline võti. Oasis ROFL toetab nii EVM-kettasid kui ka Base-kettasid.
  3. Salvestage võti – Pange oma võti turvaliselt salvestatud, kasutades selleks turvalisi meetodeid, näiteks seedri või hardware rahakotti.
  4. Ühendage võti – Kui olete valmis, ühendage oma võti vastavasse blockchainisse ja alustage turvalist juurdepääsu.

Miks valida Oasis ROFL?

  • Turvalisus: Oasis ROFL kasutab kõrgeimat turvalisust, tagades, et teie võtmed on kaitstud nii sisekui väliskeskonnas.
  • Kasutajasõbralikkus: Lihtne ja intuitiivne kasutajaliides muudab võtmete haldamise lihtsaks ja mugavaks.
  • Mitmekülgsus: Toetab mitmeid populaarseid blockchain-e, sh Ethereum, Polygon ja Base.

Tulevikku vaadates

Oasis ROFL on ainulaadne platvorm, mis avab uued võimalused krüptovaluutade ja blockchain-tehnoloogia kasutamiseks. Kasutajad saavad nüüd hõlpsalt juurdepääsuda mitmele blockchainile ühe ja sama võtmega, mis muudab nende elu oluliselt lihtsamaks.
Key Points:
  • Oasis ROFL võimaldab luua turvalisi ristaheliseid võtmeid, mis toetavad nii EVM-kettasid kui ka Base-kettasid.
  • Ristahelised võtmed tagavad turvalisuse ja lihtsa juurdepääsu mitmele blockchainile.
  • Oasis ROFL pakub tugevat integreerimist populaarsete blockchainidega, sealhulgas Ethereum, Polygon ja Base.
Disclaimer:
Oasis ROFL ei ole finantsnõustaja ega investeerimisnõustaja. Enne ristaheliste võtmete kasutamist veenduge, et olete selles protsessis hästi informeeritud ja mõistate riskid.
2026/02/20 21:16
9 minutiline lugemine

Oasis esitles raamistikku runtime off-chain logika (ROFL) jaoks, mis aitab rakendusi ehitada ja käitada off-chain’is, tagades samal ajal privaatsuse ning säilitades usaldusväärsuse on-chain verifitseeritavusega. ROFL-i kasutamine nõuab mitmeid erinevaid komponente ja protsesse.

Selles õpetuses näitan ma, kuidas luua väike TypeScript-rakendus, milles genereeritakse secp256k1 võti ROFL-i sees. Rakendus kasutab @oasisprotocol/rofl-client TypeScript SDK-d, mis suhtleb varjatud taustal appd REST API-ga. Lisaks sellele toimib TypeScript-rakendus järgmiselt:

Rakendus sisaldab lihtsat suitsukatset, mille tulemused salvestatakse logidesse.


Eeltingimused

Selleks, et saaksid seda juhendit järgida, vajad:

  • Node.js 20+ ja Docker (või Podman)
  • Oasis CLI ning vähemalt 120 TEST-tokenit oma rahakotis (Oasis Testnet faucet)
  • Mõned Base Sepiola test-EHT-id (Base Sepiola faucet)

Lisainformatsiooni saad Quickstart Prerequisites dokumentatsioonist.


Rakenduse algustamine

Esimene samm on uue rakenduse algustamine Oasis CLI abil.

oasis rofl init rofl-keygen
cd rofl-keygen

Rakenduse loomine

Testnet’il rakenduse loomise käigus tuleb depositeerida tokenid. Sel hetkel määrake 100 TEST-tokenit.

oasis rofl create --network testnet

Kui kõik läheb hästi, genereerib CLI väljundina Rakenduse ID, milleks on näiteks rofl1….


Hardhat (TypeScript) projekti algustamine

Nüüd on aeg projekti käivitada.

npx hardhat init

Kuna me demonstreerime TypeScript-rakendust, valige küsitluse käigus TypeScript ja vastake vaikimisi. Järgmiseks lisame väikesed runtime-sõltuvused, mida saab kasutada ka väljaspool Hardhat’i.

npm i @oasisprotocol/rofl-client ethers dotenv @types/node
npm i -D tsx

Hardhat’i TypeScript-mall loob automaatselt tsconfig.json. Lisame aga väikese skripti, et rakenduskood saaks kompileeritud dist/-kausta.

// tsconfig.json
{
  "compilerOptions": {
    "rootDir": "./src",
    "outDir": "./dist"
  },
  "include": ["src"]
}

Rakenduse struktuur

Selles osas lisame paar väikest TS-faili ja ühe Solidity-lepingu.

src/
├── appd.ts # õhuke wrapper @oasisprotocol/rofl-client ümber
├── evm.ts # ethers abistajad (provider, wallet, tx, deploy)
├── keys.ts # pisikesed abistajad (checksum)
└── scripts/
├── deploy-contract.ts # generiline deploy-skript kompileeritud artefaktide jaoks
└── smoke-test.ts # lõpuni viidud demo (logid)

contracts/
└── Counter.sol # näidisleping


Sissejuhatus: src/appd.ts – SDK ümberpakkimine

Siin tuleb kasutada ametlikku klienti, et suhelda appd-ga (UNIX socket). Samuti peame hoidma ekspliitselt local-dev fallback’i, kui rakendust käivitame väljaspool ROFL-i.

import { existsSync } from 'node:fs';
import { RoflClient, KeyKind, ROFL_SOCKET_PATH } from '@oasisprotocol/rofl-client';

const client = new RoflClient(); // UDS: /run/rofl-appd.sock

export async function getAppId(): Promise<string> {
  return client.getAppId();
}

/**
 * Genereerib (või deterministlikult uuesti tuletatud) secp256k1 võtme ROFL-i sees ja
 * tagastab selle 0x-prefiksiga heksakujulise stringina (ethers.js Wallet jaoks).
 *
 * Kohalik arendus AINULT (ROFL-i väljas): Kui soket puudub ja olete seadistanud
 * ALLOW_LOCAL_DEV=true ning LOCAL_DEV_SK=0x<64-hex>, kasutatakse seda väärtust.
 */
export async function getEvmSecretKey(keyId: string): Promise<string> {
  if (existsSync(ROFL_SOCKET_PATH)) {
    const hex = await client.generateKey(keyId, KeyKind.SECP256K1);
    return hex.startsWith('0x') ? hex : `0x${hex}`;
  }

  const allow = process.env.ALLOW_LOCAL_DEV === 'true';
  const pk = process.env.LOCAL_DEV_SK;
  if (allow && pk && /^0x[0-9a-fA-F]{64}$/.test(pk)) return pk;
  throw new Error(
    'rofl-appd soketit ei leitud ja LOCAL_DEV_SK ei ole antud (ainult arendus).'
  );
}

2. src/evm.ts – ethers abistajad

import { JsonRpcProvider, Wallet, parseEther, TransactionReceipt, ContractFactory } from 'ethers';

export function makeProvider(rpcUrl: string, chainId: number): JsonRpcProvider {
  return new JsonRpcProvider(rpcUrl, chainId);
}

export function connectWallet(skHex: string, rpcUrl: string, chainId: number): Wallet {
  const w = new Wallet(skHex);
  return w.connect(makeProvider(rpcUrl, chainId));
}

export async function signPersonalMessage(wallet: Wallet, msg: string): Promise<string> {
  return wallet.signMessage(msg);
}

export async function sendEth(wallet: Wallet, to: string, amountEth: string): Promise<TransactionReceipt> {
  const tx = await wallet.sendTransaction({
    to,
    value: parseEther(amountEth)
  });
  const receipt = await tx.wait();
  if (receipt == null) {
    throw new Error("Transaktsioon kukkus ära või asendati enne kinnitust.");
  }
  return receipt;
}

export async function deployContract(wallet: Wallet, abi: any[], bytecode: string, args: unknown[] = []): Promise<{ address: string; receipt: TransactionReceipt }> {
  const factory = new ContractFactory(abi, bytecode, wallet);
  const contract = await factory.deploy(...args);
  const deployTx = contract.deploymentTransaction();
  const receipt = await deployTx?.wait();
  await contract.waitForDeployment();
  if (!receipt) {
    throw new Error("Deploying TX ei ole minetud.");
  }
  return { address: contract.target as string, receipt };
}

3. src/keys.ts – pisikesed abistajad

import { Wallet, getAddress } from 'ethers';

export function secretKeyToWallet(skHex: string): Wallet {
  return new Wallet(skHex);
}

export function checksumAddress(addr: string): string {
  return getAddress(addr);
}

4. src/scripts/smoke-test.ts – üksik lõpuni viidud voog

See on oluline samm, kuna see skript täidab mitmeid funktsioone:

  • Prindi Rakenduse ID (ROFL-i sees), aadress ja allkirjastatud sõnum
  • Oota rahastamist
  • Jaota Counter-leping
import "dotenv/config";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { getAppId, getEvmSecretKey } from "../appd.js";
import { secretKeyToWallet, checksumAddress } from "../keys.js";
import { makeProvider, signPersonalMessage, sendEth, deployContract } from "../evm.js";
import { formatEther, JsonRpcProvider } from "ethers";

const RPC_URL = process.env.BASE_RPC_URL ?? "https://sepolia.base.org";
const CHAIN_ID = Number(process.env.BASE_CHAIN_ID ?? "84532");
const KEY_ID = process.env.KEY_ID ?? "evm:base:sepolia";

function sleep(ms: number): Promise<void> {
  return new Promise((r) => setTimeout(r, ms));
}

async function waitForFunding(provider: JsonRpcProvider, addr: string, minWei: bigint = 1n, timeoutMs = 15 * 60 * 1000, pollMs = 5_000): Promise<bigint> {
  const start = Date.now();
  while (Date.now() - start < timeoutMs) {
    const bal = await provider.getBalance(addr);
    if (bal >= minWei) return bal;
    console.log(`Ootame rahastamist... praegune saldo=${formatEther(bal)} ETH`);
    await sleep(pollMs);
  }
  throw new Error("Aegumine rahastamise ootamisel.");
}

async function main() {
  const appId = await getAppId().catch(() => null);
  console.log(`ROFL Rakenduse ID: ${appId ?? "(ROFL-i väljas ei saada)"}`);
  const sk = await getEvmSecretKey(KEY_ID);
  const wallet = secretKeyToWallet(sk).connect(makeProvider(RPC_URL, CHAIN_ID));
  const addr = checksumAddress(await wallet.getAddress());
  console.log(`EVM-aadress (Base Sepolia): ${addr}`);
  const msg = "hello from rofl";
  const sig = await signPersonalMessage(wallet, msg);
  console.log(`Allkirjastatud sõnum: "${msg}"`);
  console.log(`Allkiri: ${sig}`);
  const provider = wallet.provider as JsonRpcProvider;
  let bal = await provider.getBalance(addr);
  if (bal === 0n) {
    console.log("Palun rahastage ülaltoodud aadress Base Sepolia ETH-ga, et jätkata.");
    bal = await waitForFunding(provider, addr);
  }
  console.log(`Saldo avastatud: ${formatEther(bal)} ETH`);
  const artifactPath = join(process.cwd(), "artifacts", "contracts", "Counter.sol", "Counter.json");
  const artifact = JSON.parse(readFileSync(artifactPath, "utf8"));
  if (!artifact?.abi || !artifact?.bytecode) {
    throw new Error("Counter artefaktis puudub ABI/võtke.");
  }
  const { address: contractAddress, receipt: deployRcpt } = await deployContract(wallet, artifact.abi, artifact.bytecode, []);
  console.log(`Counter on jaotatud aadressile ${contractAddress} (tx=${deployRcpt.hash})`);
  console.log("Suitsukatse edukalt lõppenud!");
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});

5. contracts/Counter.sol – minimaalne näidis

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Counter {
    uint256 private _value;
    event Incremented(uint256 v);
    event Set(uint256 v);

    function current() external view returns (uint256) {
        return _value;
    }

    function inc() external {
        unchecked {
            _value += 1;
        }
        emit Incremented(_value);
    }

    function set(uint256 v) external {
        _value = v;
        emit Set(v);
    }
}

6. src/scripts/deploy-contract.ts – generiline deployer

import "dotenv/config";
import { readFileSync } from "node:fs";
import { getEvmSecretKey } from "../appd.js";
import { secretKeyToWallet } from "../keys.js";
import { makeProvider, deployContract } from "../evm.js";

const KEY_ID = process.env.KEY_ID ?? "evm:base:sepolia";
const RPC_URL = process.env.BASE_RPC_URL ?? "https://sepolia.base.org";
const CHAIN_ID = Number(process.env.BASE_CHAIN_ID ?? "84532");

/**
 * Kasutus:
 *   npm run deploy-contract -- ./artifacts/MyContract.json '[arg0, arg1]'
 * Artefakt peab sisaldama { abi, bytecode }.
 */
async function main() {
  const [artifactPath, ctorJson = "[]"] = process.argv.slice(2);
  if (!artifactPath) {
    console.error("Kasutus: npm run deploy-contract -- <artifact.json> '[constructorArgsJson]'");
    process.exit(2);
  }
  const artifactRaw = readFileSync(artifactPath, "utf8");
  const artifact = JSON.parse(artifactRaw);
  const { abi, bytecode } = artifact ?? {};
  if (!abi || !bytecode) {
    throw new Error("Artefakt peab sisaldama { abi, bytecode }.");
  }
  let args: unknown[];
  try {
    args = JSON.parse(ctorJson);
    if (!Array.isArray(args)) throw new Error("Konstruktori argumendid peavad olema JSON-array");
  } catch (e) {
    throw new Error(`Konstruktori argumendid ei õnnestunud JSON-iks analüüsida: ${String(e)}`);
  }
  const sk = await getEvmSecretKey(KEY_ID);
  const wallet = secretKeyToWallet(sk).connect(makeProvider(RPC_URL, CHAIN_ID));
  const { address, receipt } = await deployContract(wallet, abi, bytecode, args);
  console.log(JSON.stringify({ contractAddress: address, txHash: receipt.hash, status: receipt.status }, null, 2));
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});

Hardhat (ainult lepingud)

Selles faasis vajame minimaalset konfiguratsiooni, et kompileerida Counter.sol.

hardhat.config.ts

import type { HardhatUserConfig } from "hardhat/config";

const config: HardhatUserConfig = {
  solidity: {
    version: "0.8.24",
    settings: {
      optimizer: { enabled: true, runs: 200 }
    }
  },
  paths: {
    sources: "./contracts",
    artifacts: "./artifacts",
    cache: "./cache"
  }
};

export default config;

Märkusena: kohalik kompileerimine on valikuline, nii et soovi korral võite selle vahele jätta. Järgmine samm on teie valik – kas kustutate olemasoleva contracts/Lock.sol faili või uuendate seda Solidity versiooniga 0.8.24.

npx hardhat compile

Konteineriseerimine

See on ülioluline samm. Siin tuleb luua Dockerfile, mis kompileerib TS-koodi ja kompileerib lepingu. Fail käivitab ka suitsukatse üks kord ja püsib siis tuimalt, kuni kontrollite logisid.

Dockerfile

FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
COPY tsconfig.json ./
COPY src ./src
COPY contracts ./contracts
COPY hardhat.config.ts ./
RUN npm run build && npx hardhat compile && npm prune --omit=dev
ENV NODE_ENV=production
CMD ["sh", "-c", "node dist/scripts/smoke-test.js || true; tail -f /dev/null"]

Järgmisena tuleb monteerida ROFL-i poolt pakutud appd soket. Olge kindlad, et protsessi käigus ei avaldata ühtegi avalikku porti.

compose.yaml

services:
  demo:
    image: docker.io/YOURUSER/rofl-keygen:0.1.0
    platform: linux/amd64
    environment:
      - KEY_ID=${KEY_ID:-evm:base:sepolia}
      - BASE_RPC_URL=${BASE_RPC_URL:-https://sepolia.base.org}
      - BASE_CHAIN_ID=${BASE_CHAIN_ID:-84532}
    volumes:
      - /run/rofl-appd.sock:/run/rofl-appd.sock

Pildi ehitamine

Oluline on meeles pidada, et ROFL töötab ainult Intel TDX-toega riistvaral. Seega, kui kompileerite pilte teises hostis, näiteks macOS-is, siis on parameetri —platform linux/amd64 lisamine ülioluline samm.

docker buildx build --platform linux/amd64 \
  -t docker.io/YOURUSER/rofl-keygen:0.1.0 --push .

Huvitav on see, et saate valida täiendava turvalisuse ja verifitseeritavuse. Lihtsalt kinnitage diges ja kasutage image: … @sha256: … koos compose.yaml-ga.


ROFL-bundle ehitamine

Enne oasis rofl build käskluse käivitamist tuleb teha üks samm. Kuna pildi ehitamine toimub konteineriseerimise järel, tuleb compose.yaml-s services.demo.image värskendada teie poolt loodud pildiga.

Lihtsate TypeScript-projektide puhul, nagu see, võib pildi suurus olla oodatust suurem. Seega on soovitatav värskendada rofl.yaml resources sektsiooni vähemalt: memory: 1024 ja storage.size: 4096.

Nüüd olete valmis!

oasis rofl build

Järgmisena saate publitseerida enklave identiteete ja konfiguratsioone.

oasis rofl update

Juurdepanek

See on üsna lihtne samm, kus juurdepanek tehakse Testnet-provider’ile.

oasis rofl deploy

Lõpuni viidud (Base Sepolia)

See on 2‑sammuline protsess, kuigi teine samm on valikuline.

Esmalt vaadake suitsukatse logisid.

oasis rofl machine logs

Kui olete kõik sammud õigesti läbi viinud, näete väljundis:

  • Rakenduse ID
  • EVM-aadress ja allkirjastatud sõnum
  • Palve rahastada aadressi
  • Kui rahastamine on tehtud, siis Counter.sol-deploying

Järgmisena kohalik arendus. Siin tuleb käivitada npm run build:all, et kompileerida TypeScript-kood ja Solidity-leping. Vajadusel võite selle sammu vahele jätta.

export ALLOW_LOCAL_DEV=true
export LOCAL_DEV_SK=0x<64-hex-dev-secret-key>   # ÄRA KASUTA TOOTMISEKS
npm run smoke-test

Turvalisus ja märkused, mida tuleb meeles pidada

  • Provider-logid ei ole rest-krüpteeritud. Seega ära kunagi logi salajasi võtmeid.
  • appd soket /run/rofl-appd.sock eksisteerib ainult ROFL-i sees.
  • Avalikel RPC-del võib olla kiirusepiirangud. Seega on soovitatav valida spetsiaalne Base RPC-URL.

Oasis GitHub-is on võtme genereerimise demo, mida saate kasutada selle õpetuse näiteks. https://github.com/oasisprotocol/demo-rofl-keygen

Nüüd, kui olete edukalt genereerinud võtme ROFL-i sees appd abil, allkirjastanud sõnumeid, jaotanud lepingu ja liigutanud ETH Base Sepoliast, andke meile kommentaarides oma tagasiside. Kiireks vestluseks Oasis’i insenerimeeskonnaga konkreetsete probleemide lahendamiseks võite oma kommentaarid postitada ametlikus Discordi dev-central kanalis.

Algselt avaldatud 20. veebruaril 2026. aastal


*Guide To Cross-Chain Key Generation (EVM / Base) With Oasis ROFL avaldati algselt Coinmonks-is Medium’is, kus inimesed jätkavad vestlust, rõhutades ja vastates sellele loole.*
Turuvõimalus
CROSS logo
CROSS hind(CROSS)
$0.10061
$0.10061$0.10061
-5.34%
USD
CROSS (CROSS) reaalajas hinnagraafik
Lahtiütlus: Sellel saidil taasavaldatud artiklid pärinevad avalikelt platvormidelt ja on esitatud ainult informatiivsel eesmärgil. Need ei kajasta tingimata MEXC seisukohti. Kõik õigused jäävad algsetele autoritele. Kui arvate, et sisu rikub kolmandate isikute õigusi, võtke selle eemaldamiseks ühendust aadressil service@support.mexc.com. MEXC ei garanteeri sisu täpsust, täielikkust ega ajakohasust ega vastuta esitatud teabe põhjal võetud meetmete eest. Sisu ei ole finants-, õigus- ega muu professionaalne nõuanne ega seda tohiks pidada MEXC soovituseks ega toetuseks.