Solidity / On-Chain Queries
Solidity / On-Chain QueriesFor fully decentralized applications on EVM-compatible chains (Ethereum, Polygon, Arbitrum, Base, BSC, etc.), you can query Localcredit scores directly on-chain via the official Localcredit Oracle contract. This enables gas-efficient, trust-minimized integrations where loan logic, limits, or rates are adjusted automatically based on a user's verified score.Contract Addresses (to be deployed and verified at launch – placeholder for now)
Mainnet (Ethereum): 0x...LocalcreditOracle
Polygon: 0x...LocalcreditOracle
Arbitrum: 0x...LocalcreditOracle
Base: 0x...LocalcreditOracle
All deployments use the same ABI.Basic Flow
User submits their Localcredit ZK proof (off-chain or via frontend).
Your contract sends a request to the Localcredit Oracle with the proof and pays the query fee in $CREDIT (or native token).
The oracle validates the proof off-chain and calls back your contract with the score.
Your contract executes logic based on the fulfilled score.
Solidity Example – Requesting a Scoresolidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface ILocalcreditOracle {
function requestScore(
bytes calldata userProof,
address callbackContract,
bytes4 callbackSelector
) external returns (uint256 requestId);
}
contract LendingPool {
ILocalcreditOracle public immutable localcreditOracle;
uint256 public constant QUERY_FEE = 10 * 1e18; // example $CREDIT fee
mapping(uint256 => address) public pendingRequests;
mapping(address => uint256) public userMaxBorrow;
constructor(address _oracle) {
localcreditOracle = ILocalcreditOracle(_oracle);
}
function applyForLoan(bytes calldata userProof) external {
// Transfer query fee from user or pool (example: user pays)
// IERC20(CREDIT).transferFrom(msg.sender, address(this), QUERY_FEE);
uint256 requestId = localcreditOracle.requestScore(
userProof,
address(this),
this.fulfillScore.selector
);
pendingRequests[requestId] = msg.sender;
}
function fulfillScore(
uint256 requestId,
uint256 score,
string memory riskTier
) external {
require(msg.sender == address(localcreditOracle), "Unauthorized");
address borrower = pendingRequests[requestId];
require(borrower != address(0), "Invalid request");
delete pendingRequests[requestId];
// Example logic based on score
if (score >= 850) {
userMaxBorrow[borrower] = 10000 * 1e6; // $10k USDC
} else if (score >= 700) {
userMaxBorrow[borrower] = 5000 * 1e6; // $5k
} else if (score >= 500) {
userMaxBorrow[borrower] = 1000 * 1e6; // $1k with collateral
} else {
userMaxBorrow[borrower] = 0; // require full collateral
}
// Emit event or proceed with loan issuance
}
}Key Features
Callback Pattern: The oracle calls back your contract with the verified score – no need to trust off-chain servers.
Fee Payment: Paid in $CREDIT (ERC-20). The exact amount is viewable via oracle.queryFee().
Proof Validation: The oracle verifies the ZK proof off-chain (using the same circuits as the REST API) before fulfilling.
Reentrancy Safe: Use standard Checks-Effects-Interactions pattern.
Advanced: Batch Queries & SubscriptionsFor high-volume protocols, subscribe on-chain to reduce per-query costs:solidity
Subscribed contracts get discounted fees and higher rate limits.Security Notes
Always verify the official oracle address from docs.localcredit.org.
Use OpenZeppelin ReentrancyGuard if handling funds in the callback.
Test thoroughly on testnet first (sandbox oracle available).
Full audited contract source, ABI, and deployment addresses will be published at launch. On-chain queries give your protocol the strongest decentralization guarantees – perfect for permissionless lending, DAOs, and under-collateralized products.Combine with the JavaScript SDK for frontend proof collection, and you have a complete end-to-end decentralized credit integration.
Last updated