Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ethereum Util Laravel Package

kornrunner/ethereum-util

kornrunner/ethereum-util is a lightweight PHP library for common Ethereum utilities, including address validation, EIP-55 checksum handling, and conversion helpers for working with keys and hex data in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require kornrunner/ethereum-util

There is no service provider, no config file, and no facade to register — the package is a single class of static helpers (namespace kornrunner\EthereumUtil; confirm with grep -n 'public static function' vendor/kornrunner/ethereum-util/src/*.php, which is genuinely the fastest way to read the whole API). That also means it works the same in Laravel, Symfony, or a bare script.

Two things to verify before your first commit:

  1. ext-bcmath is installed (wei math needs arbitrary precision — a float will silently lose precision at 18 decimals).
  2. The package's PHP constraint against your app's composer.json; it tracks recent PHP versions.

The highest-value first use case is not crypto at all — it's address hygiene on user input. Users paste addresses from block explorers, spreadsheets, and chat apps, with mixed casing, missing 0x, or trailing whitespace.

use kornrunner\EthereumUtil;

// 1. Validate before it reaches your DB or an RPC call
if (! EthereumUtil::isValidAddress($request->input('wallet'))) {
    // reject
}

// 2. Normalize to EIP-55 checksum for storage and display
$address = EthereumUtil::toChecksumAddress($request->input('wallet'));

// 3. Convert at the fiat/UI boundary only
EthereumUtil::toWei('0.05', 'ether');       // "50000000000000000"
EthereumUtil::fromWei($wei, 'ether');       // "0.05"
EthereumUtil::fromWei($gasPriceWei, 'gwei');

The unit ladder follows the Ethereum naming convention (wei, kwei/babbage, mwei/lovelace, gwei/shannon, szabo, finney, ether, kether, …), so gwei for gas display and ether for user-facing balances are both one call away.

Implementation Patterns

Store wei as a string, everywhere. Never let a wei value touch a PHP int (64-bit overflow at ~9.2 ETH) or a float. Use DECIMAL(65,0) or VARCHAR(78) in MySQL; convert to ether only in presenters/API resources.

// Eloquent cast so the model always hands you an exact string
protected $casts = ['balance_wei' => 'string'];

Wrap the statics in one injectable service. This is the single most valuable thing you can do, because it makes every call site testable and gives you one place to add caching or swap implementations later.

final class Ethereum
{
    public function toChecksum(string $address): string
    {
        return EthereumUtil::toChecksumAddress(strtolower(trim($address)));
    }

    public function weiToEther(string $wei, int $decimals = 6): string
    {
        return number_format((float) EthereumUtil::fromWei($wei, 'ether'), $decimals, '.', '');
    }
}

Note the deliberate (float) only at the display step — the lossy conversion happens on a formatted human string, never on a stored value.

Custom validation rule. Wrap the check so the error message is domain-specific and the rule is reusable across FormRequests:

class EthereumAddressRule implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! is_string($value) || ! EthereumUtil::isValidAddress($value)) {
            $fail('The :attribute must be a valid Ethereum address.');
        }
    }
}

Normalize on write, in a model mutator. Store the checksummed form so WHERE address = ? lookups are consistent and copy-paste out of your UI is verifiable by the user.

Hashing for topics and selectors. keccak256 gives you ERC-20 event topics and 4-byte function selectors without pulling in a full ABI library:

$topic0 = EthereumUtil::keccak256('Transfer(address,address,uint256)');
// 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
$selector = substr(EthereumUtil::keccak256('transfer(address,uint256)'), 0, 10);
// 0xa9059cbb

These two constants are also excellent smoke tests that your install is wired up correctly.

Know where the boundary is. This package does not sign transactions, encode ABI payloads, or derive addresses from private keys. For those, pair it with kornrunner/ethereum-address (key → address), kornrunner/ethereum-offline-raw-tx (build/sign), or a JSON-RPC client. Use ethereum-util purely as the formatting/validation layer in front of them.

Gotchas and Tips

  • Never pass a float to toWei. toWei(0.1, 'ether') is a precision bug, not a convenience. Pass strings: toWei('0.1', 'ether'). If a value arrives as a float from an API, cast via number_format($v, 18, '.', '') first, and treat that as a code smell.
  • Keccak-256 ≠ SHA3-256. Ethereum uses the pre-standardisation Keccak padding. PHP's built-in hash('sha3-256', ...) produces different output. Always go through this package (it depends on kornrunner/keccak), and never "optimise" it away to a native hash — your event topics will silently stop matching.
  • EIP-55 validation is subtler than a regex. Per the spec, an all-lowercase or all-uppercase address is valid (there's no checksum to verify), while a mixed-case address must match its checksum. A mixed-case typo like 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAeD should fail. Test this explicitly — plenty of implementations only do the regex check.
  • Lowercase before checksumming. Feeding an already-checksummed address back into toChecksumAddress is usually fine, but lowercasing first makes the operation idempotent and removes a class of "works in dev, not in prod" bugs where upstream data has odd casing.
  • fromWei returns a string with full precision, not a formatted number. fromWei('1', 'ether') is '0.000000000000000001'; you'll still need number_format/bcdiv for display, and you should decide explicitly whether to round or truncate. Round-trip test fromWei(toWei($x)) in your suite.
  • 0x prefix handling is inconsistent across Ethereum tooling. Decide once (I'd store with 0x) and strip/restore at the edges; if the package offers a stripZero-style helper, use it rather than ltrim($x, '0x') — that's a character-class trim and will eat leading zeros from the payload.
  • Unit names are lowercase strings. 'Ether' or 'ETH' won't resolve. Validate user-supplied units against an allowlist before handing them over.
  • Statics can't be mocked. If you call EthereumUtil:: directly from a controller you cannot stub it in a test and you cannot swap it if EIP-55 or a unit definition changes. The thin wrapper above costs 20 lines and pays for itself immediately.
  • Pin the version. 8 stars and zero dependents means a real bus-factor; the API is small and MIT, so pinning plus your wrapper means you can vendor or fork the class into app/Support in an afternoon if it ever goes stale.
  • Debugging checklist: if a checksum looks wrong, verify against the canonical EIP-55 vector 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed; if a hash looks wrong, check the 0xddf252ad… Transfer topic above; if a number looks wrong, check whether bcmath is actually loaded (php -m | grep bcmath) before you suspect the library.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings