← Semua pembelajaran / Blockchain Nol → RWA
Fase 3 · Integrasi Backend Java & PHP

web3.php — integrasi PHP ke smart contract

Ekosistem PHP tidak punya satu pustaka Web3 sedominan web3j di Java. web3.php adalah pilihan komunitas yang paling banyak dipakai — lebih ringan, dan mengharuskanmu memahami beberapa hal yang di Java otomatis dibungkus generator.

Sumber asli github.com Resmi Rangkuman ~7 menit baca

Intisari

  • composer require web3p/web3.php — tidak ada generator ABI-ke-class seperti web3j; kamu memanggil fungsi lewat nama string dan array parameter.
  • Panggilan read lewat $contract->call(...) — asinkron berbasis callback, bukan berbasis await/blocking seperti web3j.
  • web3.php tidak menandatangani transaksi secara built-in selengkap web3j — pola umum: encode data transaksi lewat web3.php, tanda tangani manual dengan pustaka secp256k1/kornrunner/keccak, baru kirim lewat eth_sendRawTransaction.
  • Untuk kebutuhan produksi yang lebih berat, banyak tim PHP memilih memanggil JSON-RPC langsung lewat Guzzle sebagai pengganti sebagian fitur web3.php yang belum lengkap.
  • Prinsip read vs write dari materi sebelumnya berlaku identik — bahasa berubah, konsepnya tidak.

Instalasi

composer require web3p/web3.php

Koneksi & read

use Web3\Web3;
use Web3\Contract;

$web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/API_KEY_KAMU');
$abi  = file_get_contents(__DIR__ . '/GoldToken.abi.json');

$contract = new Contract($web3->provider, $abi);
$contract->at('0xAlamatKontrakYangSudahDiDeploy');

$contract->call('balanceOf', '0xAlamatPengguna', function ($err, $hasil) {
    if ($err !== null) {
        error_log('Gagal membaca saldo: ' . $err->getMessage());
        return;
    }
    // $hasil[0] berupa BigNumber (php-bignum) — bukan int PHP biasa,
    // karena uint256 Solidity jauh melebihi jangkauan integer PHP.
    echo 'Saldo: ' . $hasil[0]->toString() . PHP_EOL;
});

Kenapa lewat callback, bukan nilai kembalian langsung. web3.php dibangun di atas model request asinkron gaya JavaScript lama — call() tidak return hasilnya, ia memanggil function ($err, $hasil) yang kamu berikan setelah respons HTTP dari node provider datang. Ini beda paradigma dari web3j yang blocking secara default; kalau kode PHP-mu butuh hasilnya secara sinkron (mis. di dalam controller Laravel biasa), bungkus pemanggilan ini dan tunggu callback-nya selesai sebelum lanjut — atau pertimbangkan memanggil JSON-RPC langsung lewat Guzzle sinkron sebagai alternatif yang lebih mudah diprediksi.

Write: menandatangani transaksi secara manual

Ini beda signifikan dari web3j. web3.php tidak menyediakan Credentials siap pakai yang menandatangani transaksi otomatis — kamu perlu merakit transaksi mentah dan menandatanganinya sendiri, biasanya dengan bantuan pustaka kornrunner/secp256k1:

use Web3\Utils;

// 1. Ambil nonce terkini akun pengirim
$web3->eth->getTransactionCount('0xAlamatPengirim', 'pending', function ($err, $nonce) use (&$txNonce) {
    $txNonce = $nonce;
});

// 2. Encode data pemanggilan fungsi lewat ABI kontrak
$data = $contract->getData('mintGold', '0xAlamatPengguna', 100, 'bukti-001');

// 3. Rakit lalu tanda tangani transaksi (disederhanakan — pustaka nyata
//    menangani RLP encoding dan skema EIP-1559 secara lebih eksplisit)
$transaction = new \Web3p\EthereumTx\Transaction([
    'nonce'                => Utils::toHex($txNonce, true),
    'to'                   => '0xAlamatKontrak',
    'value'                => '0x0',
    'gasLimit'             => '0x30d40',
    'maxFeePerGas'         => '0x9502f9000',
    'maxPriorityFeePerGas' => '0x9502f900',
    'data'                 => $data,
]);

$raw = $transaction->sign('PRIVATE_KEY_TESTNET_SAJA');

// 4. Kirim transaksi yang sudah ditandatangani
$web3->eth->sendRawTransaction('0x' . $raw, function ($err, $txHash) {
    echo 'Terkirim, hash: ' . $txHash . PHP_EOL;
});

Ini kenapa web3.php terasa lebih "manual" dibanding web3j. web3j menyembunyikan seluruh proses di atas di balik satu panggilan .send() karena pustakanya menyediakan lapisan Credentials + RawTransactionManager terintegrasi. Ekosistem PHP tidak sedewasa itu untuk Web3 — kamu (atau pustaka pembantu tambahan) yang merakit nonce, encoding, dan tanda tangan sendiri. Untuk sistem produksi, langkah 3 di atas tidak boleh memuat private key mentah seperti contoh ini — lihat Fase 4 untuk kenapa, dan Fase 5 untuk pola signing lewat AWS KMS yang menghindari private key pernah ada sebagai string PHP biasa sama sekali.

Kapan memanggil JSON-RPC langsung lewat Guzzle

Untuk method JSON-RPC yang belum terbungkus rapi di web3.php, atau saat kamu ingin kontrol penuh atas retry dan timeout, memanggil endpoint node provider langsung lewat HTTP client PHP biasa sering lebih dapat diprediksi daripada memaksakan abstraksi web3.php:

$response = $httpClient->post($rpcUrl, [
    'json' => [
        'jsonrpc' => '2.0',
        'method'  => 'eth_getTransactionReceipt',
        'params'  => [$txHash],
        'id'      => 1,
    ],
]);

$receipt = json_decode($response->getBody(), true)['result'];

Latihan: pakai web3.php untuk memanggil balanceOf() kontrak GoldToken milikmu dari CLI PHP sederhana (php baca-saldo.php). Bandingkan hasilnya dengan panggilan web3j di materi sebelumnya untuk kontrak dan address yang sama — keduanya wajib menghasilkan angka yang identik, karena keduanya cuma dua cara berbeda memanggil eth_call yang sama.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.