Install
$ agentstack add skill-0gfoundation-0g-agent-skills-interact-contract ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Interact with 0G Chain Contracts
Metadata
- Category: chain
- SDK:
ethers^6.13.0 - Activation Triggers: "call contract", "read contract", "interact", "write contract", "contract
function"
Purpose
Read from and write to deployed smart contracts on 0G Chain using ethers v6. Covers view functions, state-changing transactions, event listening, and gas estimation.
Prerequisites
- Node.js >= 18
ethers^6.13.0 installed- Contract ABI and address
.envwithPRIVATE_KEY,RPC_URL
Quick Workflow
Read (View Functions)
- Create provider (no wallet needed for reads)
- Create contract instance with ABI and address
- Call view function
Write (State Changes)
- Create provider and wallet
- Create contract instance with wallet as signer
- Call state-changing function
- Wait for transaction confirmation
Core Rules
ALWAYS
- Use ethers v6 syntax throughout
- Use
await contract.getAddress()(notcontract.address) - Use
await contract.waitForDeployment()(not.deployed()) - Wait for transaction confirmation with
tx.wait() - Use native
BigInt(notBigNumber)
NEVER
- Use ethers v5 patterns
- Skip transaction confirmation for important operations
- Hardcode contract addresses in source (use
.env)
Code Examples
Read Contract State
import { ethers } from 'ethers';
import 'dotenv/config';
const ABI = [
'function getValue() view returns (uint256)',
'function balanceOf(address) view returns (uint256)',
'function owner() view returns (address)',
];
async function readContract() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const contract = new ethers.Contract(process.env.CONTRACT_ADDRESS!, ABI, provider);
const value = await contract.getValue();
console.log('Value:', value.toString());
const balance = await contract.balanceOf(process.env.WALLET_ADDRESS!);
console.log('Balance:', ethers.formatEther(balance));
const owner = await contract.owner();
console.log('Owner:', owner);
}
Write to Contract
async function writeContract() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const ABI = [
'function setValue(uint256) external',
'function transfer(address, uint256) external returns (bool)',
];
const contract = new ethers.Contract(process.env.CONTRACT_ADDRESS!, ABI, wallet);
// Simple write
const tx = await contract.setValue(42);
const receipt = await tx.wait();
console.log('Tx hash:', receipt.hash);
console.log('Gas used:', receipt.gasUsed.toString());
// Write with value
const tx2 = await contract.transfer('0xRecipient...', ethers.parseEther('1.0'));
await tx2.wait();
}
Listen for Events
async function listenForEvents() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const ABI = [
'event Transfer(address indexed from, address indexed to, uint256 amount)',
'event ValueChanged(uint256 newValue)',
];
const contract = new ethers.Contract(process.env.CONTRACT_ADDRESS!, ABI, provider);
// Real-time listener
contract.on('ValueChanged', (newValue) => {
console.log('Value changed to:', newValue.toString());
});
contract.on('Transfer', (from, to, amount) => {
console.log(`Transfer: ${from} → ${to}: ${ethers.formatEther(amount)}`);
});
// Query past events
const filter = contract.filters.Transfer();
const events = await contract.queryFilter(filter, -1000); // Last 1000 blocks
console.log(`Found ${events.length} transfer events`);
}
Gas Estimation
async function estimateGas() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const ABI = ['function setValue(uint256) external'];
const contract = new ethers.Contract(process.env.CONTRACT_ADDRESS!, ABI, wallet);
const gasEstimate = await contract.setValue.estimateGas(42);
console.log('Estimated gas:', gasEstimate.toString());
// Execute with gas buffer
const tx = await contract.setValue(42, {
gasLimit: (gasEstimate * 120n) / 100n, // 20% buffer
});
await tx.wait();
}
Using Full ABI (from compilation)
import * as fs from 'fs';
async function interactWithArtifact() {
const artifact = JSON.parse(
fs.readFileSync('./artifacts/contracts/MyContract.sol/MyContract.json', 'utf8'),
);
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
const contract = new ethers.Contract(process.env.CONTRACT_ADDRESS!, artifact.abi, wallet);
// Now use any function from the contract
const value = await contract.getValue();
console.log('Value:', value.toString());
}
ethers v6 Quick Reference
| Operation | v5 (DO NOT USE) | v6 (CORRECT) | | ------------ | -------------------------------------- | ------------------------------------ | | Parse ether | ethers.utils.parseEther("1") | ethers.parseEther("1") | | Format ether | ethers.utils.formatEther(x) | ethers.formatEther(x) | | Big numbers | BigNumber.from(42) | 42n (native BigInt) | | Get address | contract.address | await contract.getAddress() | | Wait deploy | await contract.deployed() | await contract.waitForDeployment() | | Provider | new ethers.providers.JsonRpcProvider | new ethers.JsonRpcProvider |
Anti-Patterns
// BAD: ethers v5 patterns
const value = ethers.utils.parseEther('1.0'); // v5!
const provider = new ethers.providers.JsonRpcProvider(url); // v5!
const big = BigNumber.from(42); // v5!
// BAD: Not waiting for confirmation
await contract.setValue(42); // Fire and forget — bad!
// BAD: Hardcoded addresses
const contract = new ethers.Contract('0x123...', abi, wallet);
Common Errors & Fixes
| Error | Cause | Fix | | ----------------------- | ------------------------ | ------------------------------ | | execution reverted | Require/revert condition | Check function parameters | | insufficient funds | Wallet empty | Fund wallet | | nonce too low | Pending tx | Wait or set nonce manually | | cannot estimate gas | Function will revert | Check args and contract state | | call revert exception | View function reverted | Check function exists and args |
Related Skills
- [Deploy Contract](../deploy-contract/SKILL.md) — deploy contracts first
- [Scaffold Project](../scaffold-project/SKILL.md) — project setup
- [Storage + Chain](../../cross-layer/storage-plus-chain/SKILL.md) — on-chain + storage
References
- [Chain Patterns](../../../patterns/CHAIN.md)
- [Network Config](../../../patterns/NETWORK_CONFIG.md)
- ethers v6 Docs
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: 0gfoundation
- Source: 0gfoundation/0g-agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.