The Ballerina Web3 Tool automatically generates type-safe Ballerina client connectors from Ethereum smart contract ABI (Application Binary Interface) JSON files. Instead of manually writing boilerplate code to interact with smart contracts, point this tool at an ABI file and get a ready-to-use Ballerina client with methods for every contract function, plus built-in Ethereum RPC helpers.
- Smart contract client — each function in your Solidity contract becomes a Ballerina resource method.
- Ethereum RPC helpers —
getAccounts(),getBalance(),getBlockNumber(),getTransactionCount(), plus Wei ⟷ Ether conversions out of the box. - Utility functions — parameter encoding, hex conversion, and more, generated alongside the client.
Pull the tool from Ballerina Central:
bal tool pull web3Given a SimpleStorage.json ABI file:
bal web3 -a SimpleStorage.jsonThis generates two files in your current directory:
| File | Description |
|---|---|
main.bal |
A Web3 client class with contract methods and Ethereum RPC helpers |
utils.bal |
Helper functions for parameter encoding and hex conversion |
You can then use the generated client:
import ballerina/io;
public function main() returns error? {
Web3 client = check new ("http://localhost:8545", "0xYourContractAddress");
// Call a contract method
decimal value = check client->/retrieve.post();
io:println("Stored value: ", value);
// Use built-in helpers
decimal balance = check client.getBalance("0xYourAddress");
io:println("Balance in ETH: ", client.weiToEther(balance));
}bal web3 -a <abi-file-path> [-o <output-directory>]| Option | Description | Required |
|---|---|---|
-a, --abi |
Path to the Solidity ABI JSON file | Yes |
-o, --output |
Output directory (defaults to current directory) | No |
-h, --help |
Display help information | No |
# Generate client from a token contract ABI
bal web3 -a Token.json
# Specify an output directory
bal web3 -a Token.json -o ./generated| Method | Signature | Description |
|---|---|---|
init |
init(string api, string address) returns error? |
Initialize with RPC URL and contract address |
setContractAddress |
setContractAddress(string address) |
Change the target contract address |
getAccounts |
getAccounts() returns string[]|error |
List available accounts |
getBalance |
getBalance(string address) returns decimal|error |
Get account balance in Wei |
getBlockNumber |
getBlockNumber() returns decimal|error |
Get the latest block number |
getTransactionCount |
getTransactionCount(string address) returns decimal|error |
Get transaction count for an address |
weiToEther |
weiToEther(decimal weiAmount) returns decimal |
Convert Wei to Ether |
ethToWei |
ethToWei(decimal etherValue) returns decimal |
Convert Ether to Wei |
Each function defined in the smart contract ABI becomes a Ballerina resource method. For example, a Solidity store(uint256) function generates:
resource isolated function post store(decimal _value) returns error? { ... }| Solidity Type | Ballerina Type |
|---|---|
uint8, uint256, int8, int256, etc. |
decimal |
bool |
boolean |
address |
string |
string |
string |
bytes |
string |
T[] (arrays) |
T[] |
| Multiple return values | record { ... } |
ABI JSON File
│
▼
┌──────────┐
│ AbiReader │ ── Parses JSON, extracts function signatures
└────┬─────┘
│
▼
┌────────────────┐
│ ClientGenerator │
├────────┬───────┘
│ │
│ ┌────▼──────────────────┐
│ │ StaticFunctionGenerator │ ── Adds standard Ethereum RPC methods
│ └───────────────────────┘
│
│ ┌────▼───────────────────┐
│ │ DynamicFunctionGenerator │ ── Generates contract-specific methods
│ │ • Keccak256 function selectors
│ │ • Parameter encoding
│ │ • Response decoding
│ └────────────────────────┘
│
▼
┌───────────┐
│ Formatter │ ── Formats via Ballerina compiler APIs
└─────┬─────┘
│
▼
main.bal + utils.bal
-
OpenJDK 21 — Adoptium or Oracle JDK
Set
JAVA_HOMEto point to your JDK installation. -
GitHub credentials with read package permissions:
export packageUser=<Username> export packagePAT=<Personal access token>
# Build the project
./gradlew clean build
# Run tests
./gradlew clean test
# Build without tests
./gradlew clean build -x test
# Publish to Maven local
./gradlew clean build publishToMavenLocal
# Publish to local Ballerina Central
./gradlew clean build -PpublishToLocalCentral=true
# Publish to Ballerina Central
./gradlew clean build -PpublishToCentral=true| Dependency | Purpose |
|---|---|
Jackson (jackson-databind) |
ABI JSON parsing |
| Ballerina Compiler APIs | Syntax tree generation & formatting |
| Picocli | CLI argument parsing |
| BouncyCastle | Keccak256 hashing for function selectors |
| Commons IO | File utilities |
bytestypes are currently mapped tostringrather than byte arrays.tupletypes are not yet supported.- Multiple output decoding is basic — record types are generated but decoding logic is minimal.
As an open-source project, Ballerina welcomes contributions from the community.
Check for open issues that interest you, or submit a pull request. See the contribution guidelines for details.
All contributors are encouraged to read the Ballerina Code of Conduct.
- Discord — Chat with the community
- Stack Overflow — Ask technical questions (
#ballerina) - Ballerina Performance Benchmarks
This project is licensed under the Apache License 2.0.