developer hub

Buduj na Octra.

// AML · OVM · HFHE · Circles · RPC · quickstart

01 · quickstart

Od zera do działającego kontraktu.

1

Portfel

Utwórz portfel na wallet.octra.org lub CLI. Format adresu: oct + base58(sha256(pubkey[32:])). Zapisz seed phrase offline — nie ma odzyskiwania.

2

Testnet OCT z faucetu

Discord #faucet → wyślij adres → otrzymasz OCT. Potrzebujesz min. 200 000 OU (0.2 OCT) na deploy + margines na opłatę transakcji.

3

Kontrakt AML

Napisz contract.aml (patrz sekcja AML). Krytyczne: słowo contract (nie program), bool jako int 0/1, opłata recommendedFee × 1.5.

4

Deploy

POST /deploy_contract z payload: kontrakt AML, ou=200000, podpisana transakcja. Zwraca adres kontraktu w formacie oct....

5

Wywołaj i zweryfikuj

POST /call_contract z adresem i nazwą funkcji. Sprawdź na octrascan.io — pola zaszyfrowane widoczne jako hex ciphertext.

02 · język aml

Actra Markup Language.

Własny język kontraktów Octra kompilowany do WASM. Składnia inspirowana Rust/OCaml z natywnymi typami zaszyfrowanymi.

Zasady krytyczne:
contract — nie program
→ bool przechowywany jako int (0 lub 1)
→ brak private fn
value = kwota OCT w transakcji
→ deploy: ou=200000
→ fee: recommendedFee() × 1.5

// hello_world.aml
contract HelloWorld {
  state {
    counter:  int,
    secret:   ct_int,   // zaszyfrowana
    is_open:  int       // bool jako 0/1
  }

  fn init() {
    self.counter  = 0
    self.is_open  = 1
    self.secret   = encrypt(42)
  }

  fn increment() {
    require(self.is_open == 1)
    self.counter = self.counter + 1
  }

  fn add_to_secret(amount: ct_int) {
    self.secret = ct_add(self.secret, amount)
    // secret nigdy nie jest odszyfrowany
  }

  fn close() {
    require(caller == admin)
    self.is_open = 0
  }
}
// private_vault.aml — przykład produkcyjny
contract PrivateVault {
  state {
    balance: ct_int,
    owner:   address,
    locked:  int
  }

  fn init() {
    self.owner   = caller
    self.balance = encrypt(0)
    self.locked  = 0
  }

  fn deposit() {
    require(caller == self.owner)
    require(self.locked == 0)
    // value = OCT przesłany z transakcją
    self.balance = ct_add(
      self.balance,
      encrypt(value)
    )
  }

  fn withdraw(amount: ct_int) {
    require(caller == self.owner)
    // sprawdź saldo bez odszyfrowywania
    require(ct_gte(self.balance, amount))
    self.balance = ct_sub(self.balance, amount)
    send(caller, decrypt(amount))
  }

  fn lock() {
    require(caller == self.owner)
    self.locked = 1
  }
}
03 · operacje hfhe

Dostępne operacje na zaszyfrowanych danych.

Brak ct_mul — mnożenie ciphertext × ciphertext nie jest obsługiwane w aktualnej wersji HFHE. Mnożenie plaintext × ciphertext jest możliwe. Planowane w kolejnych wersjach.

operacjasygnaturaopisstatus
ct_addct_int + ct_int → ct_intdodawanie zaszyfrowanych liczb✓ dostępna
ct_subct_int - ct_int → ct_intodejmowanie zaszyfrowanych liczb✓ dostępna
ct_gtect_int >= ct_int → ct_boolporównanie ≥ bez odszyfrowywania✓ dostępna
ct_andct_bool & ct_bool → ct_boollogiczne AND na zaszyfrowanych bitach✓ dostępna
ct_orct_bool | ct_bool → ct_boollogiczne OR na zaszyfrowanych bitach✓ dostępna
ct_not!ct_bool → ct_boolnegacja zaszyfrowanego bitu✓ dostępna
encrypt()int → ct_intszyfrowanie plaintext wartości✓ dostępna
decrypt()ct_int → intodszyfrowanie (tylko uprawniony klucz)✓ dostępna
ct_mulct_int × ct_int → ct_intmnożenie ciphertext × ciphertext✗ brak
04 · rpc reference

API endpoints.

methodendpointopis
POST/send_transactionwyślij podpisaną transakcję
POST/deploy_contractdeployuj kontrakt AML (ou=200000)
POST/call_contractwywołaj funkcję kontraktu
GET/get_balance/:addresspobierz saldo (zaszyfrowane lub pub)
GET/get_transaction/:hashszczegóły transakcji
GET/get_contract/:addressstan kontraktu (view)
GET/recommended_feeaktualna rekomendowana opłata
GET/network_statusstatus sieci, TPS, blockheight
// przykład: deploy_contract
// POST https://rpc.octra.org/deploy_contract
{
  "contract_code": "contract HelloWorld { ... }",
  "ou": 200000,
  "from": "oct1abc...xyz",
  "fee": 1500,        // recommendedFee × 1.5
  "signature": "ed25519_sig_hex..."
}

// Response
{
  "contract_address": "oct9QYq...xyz",
  "tx_hash": "0xabc123...",
  "status": "confirmed"
}
05 · przykłady

Gotowe wzorce kontraktów.

// sealed auction — zapieczętowana aukcja

sealed_auction.aml
contract SealedAuction {
  state {
    best_bid:   ct_int,
    best_addr:  address,
    ended:      int,
    admin:      address
  }

  fn init() {
    self.admin    = caller
    self.best_bid = encrypt(0)
    self.ended    = 0
  }

  fn bid(amount: ct_int) {
    require(self.ended == 0)
    // porównaj oferty bez odszyfrowywania
    if ct_gte(amount, self.best_bid) {
      self.best_bid  = amount
      self.best_addr = caller
    }
  }

  fn finalize() -> address {
    require(caller == self.admin)
    self.ended = 1
    return self.best_addr
  }
}

// private voting — zaszyfrowane głosowanie

private_vote.aml
contract PrivateVote {
  state {
    yes_count: ct_int,
    no_count:  ct_int,
    ended:     int,
    admin:     address
  }

  fn init() {
    self.admin     = caller
    self.yes_count = encrypt(0)
    self.no_count  = encrypt(0)
    self.ended     = 0
  }

  fn vote(choice: ct_bool) {
    // choice=1 → tak, choice=0 → nie
    require(self.ended == 0)
    self.yes_count = ct_add(
      self.yes_count,
      ct_and(choice, encrypt(1))
    )
    self.no_count = ct_add(
      self.no_count,
      ct_and(ct_not(choice), encrypt(1))
    )
  }

  fn result() -> ct_bool {
    require(self.ended == 1)
    return ct_gte(yes_count, no_count)
  }
}