Oracle Service
Overview
Key Features
TEE Protection
All oracle operations run within a Trusted Execution Environment (TEE), ensuring data integrity and confidentiality.
Flexible Data Sources
Connect to almost any API or data source, including REST APIs, databases, and streaming services.
Custom Data Transformations
Transform and process the data before it reaches your smart contract to ensure it's in the right format.
Multiple Consensus Mechanisms
Configure your oracle to use different consensus mechanisms for data validation, including majority voting and threshold signatures.
Architecture
The Oracle Service consists of the following components:
- Data Source Manager: Manages connections to external data sources
- Request Processor: Handles oracle data requests
- Data Validator: Validates and formats data from external sources
- Blockchain Integration: Delivers data to Neo N3 contracts
- Storage Layer: Records request history and data for auditing
- TEE Runner: Executes data retrieval in a secure environment
Request Flow
The service follows this basic flow for delivering data:
- Request Submission:
- Smart contract or user requests data via the API
- Request includes data source, parameters, and callback information
- Data Collection:
- Oracle service retrieves data from the specified external source
- Data is validated and formatted according to request parameters
- On-chain Delivery:
- Validated data is delivered to the requesting contract
- Transaction is signed and sent to the blockchain
- Verification:
- Smart contract can verify the data integrity
- Data provenance is recorded for auditing
Supported Data Sources
The service supports multiple types of data sources:
- REST APIs: HTTP/HTTPS endpoints with JSON or XML responses
- WebSockets: Real-time data streams
- File Systems: CSV, JSON, or XML files
- IPFS: Decentralized file system
- Databases: SQL or NoSQL databases
- Custom Sources: Extendable interface for custom data sources
Authentication Methods
The service supports various authentication methods for external APIs:
- API Key authentication
- OAuth 2.0
- JWT tokens
- Basic authentication
- Custom authentication headers
Security Best Practice
Smart Contract Integration
To integrate the Oracle Service with your Neo N3 smart contracts, you need to implement a specific interface that can handle callbacks from the Oracle Service.
Example Oracle Consumer Contract
1// Oracle consumer contract interface
2type OracleConsumer interface {
3 // Request data from the oracle service
4 RequestData(requestID uint64, url string, path string, callback string) bool
5
6 // Callback for receiving the data
7 ReceiveData(requestID uint64, data []byte, proof []byte) bool
8
9 // Get the last received data
10 GetLastData() (data []byte, timestamp uint64)
11}
Once you have implemented this interface, your contract can request data from the Oracle Service and receive the results via a callback.
API Endpoints
Admin API
GET /api/v1/oracles
- List all oracle data feedsGET /api/v1/oracles/:id
- Get details of a specific oraclePOST /api/v1/oracles
- Create a new oracle data feedPUT /api/v1/oracles/:id
- Update an oracle data feedDELETE /api/v1/oracles/:id
- Delete an oracle data feedGET /api/v1/oracles/:id/requests
- List requests for an oracleGET /api/v1/oracles/requests/:id
- Get details of a specific request
Public API
POST /api/v1/public/oracles/request
- Submit a new oracle data requestGET /api/v1/public/oracles/request/:id
- Get the status and result of a requestGET /api/v1/public/oracles/data/:id
- Get historically stored oracle data
Creating an Oracle Request
Here's an example of creating a new oracle request:
1{
2 "url": "https://api.coingecko.com/api/v3/simple/price?ids=neo&vs_currencies=usd",
3 "method": "GET",
4 "headers": {
5 "Content-Type": "application/json"
6 },
7 "path": "$.neo.usd",
8 "transform": "parseInt(data * 100)",
9 "callback_address": "0x1234567890abcdef1234567890abcdef12345678",
10 "callback_method": "ReceivePrice",
11 "gas_fee": 0.5
12}
Request Parameters
Oracle requests support the following parameters:
url
: The API endpoint URL to fetch data frommethod
: HTTP method (GET, POST, etc.)headers
: Custom HTTP headers for the requestbody
: Request body for POST/PUT requestsauth_type
: Authentication type (API_KEY, OAUTH, BASIC, etc.)auth_params
: Authentication parameters (keys, tokens, etc.)path
: JSONPath or XPath expression to extract specific datatransform
: Transformation function to apply to the datacallback_address
: Neo N3 contract address to receive the datacallback_method
: Method to call with the datagas_fee
: GAS fee to pay for the callback transaction
JSONPath Examples
The Oracle Service uses JSONPath expressions to extract specific data from complex JSON responses. Here are some examples:
1// Simple price data
2$.neo.usd
3
4// First item in an array
5$.results[0].price
6
7// Multiple data points
8$.data.markets[?(@.symbol=="NEO")].price
9
10// Complex filtering
11$.data.pairs[?(@.base=="NEO" && @.quote=="USD")].price
Security Features
- All oracle operations execute within the TEE environment
- Data signatures ensure integrity from source to blockchain
- Rate limiting prevents API abuse and DoS attacks
- Input validation prevents injection attacks
- Secure credential storage for API authentication
- Detailed audit logs for all requests and responses
Performance Considerations
The Oracle Service includes several optimizations for performance:
- Connection pooling for efficient API requests
- Caching of frequently requested data
- Batched blockchain transactions for multiple data points
- Automatic retry mechanisms for failed requests
- Prioritization of time-sensitive requests
Use Cases
Financial Data
Token prices, exchange rates, interest rates, and other financial metrics.
Sports & Gaming
Sports results, statistics, and real-time game data for betting and gaming platforms.
Weather Data
Current conditions, forecasts, and historical data for weather-dependent applications.
IoT Integration
Data from IoT sensors and devices to trigger smart contract actions.
Social Media
Monitor for specific events, mentions, or trends on social platforms.
Supply Chain
Track and verify shipments, inventory levels, and logistics information.
Monitoring and Metrics
The service provides comprehensive monitoring capabilities:
- Request volume and success rate by data source
- Response time for external APIs
- Data validation success rates
- Gas usage for on-chain operations
- Error rates by source and type
- Request distribution by client
These metrics are exposed via Prometheus endpoints and can be visualized using Grafana dashboards.
Example: Creating a Price Oracle
Let's create a simple price oracle that fetches Neo token price from CoinGecko and reports it to a smart contract:
1. Create an Oracle Definition
1{
2 "name": "NeoPriceOracle",
3 "description": "Neo/USD price oracle using CoinGecko API",
4 "source": {
5 "type": "rest",
6 "url": "https://api.coingecko.com/api/v3/simple/price?ids=neo&vs_currencies=usd",
7 "method": "GET",
8 "headers": {
9 "Accept": "application/json"
10 }
11 },
12 "extraction": {
13 "path": "$.neo.usd",
14 "transform": "parseFloat(data) * 100000000" // Convert to integer with 8 decimal places
15 },
16 "schedule": {
17 "type": "interval",
18 "interval": 3600 // Update hourly
19 },
20 "delivery": {
21 "contract_hash": "0x1234567890abcdef1234567890abcdef12345678",
22 "method": "UpdatePrice",
23 "gas": 1.0
24 }
25}
2. Create a Consumer Smart Contract
1using Neo.SmartContract.Framework;
2using Neo.SmartContract.Framework.Services;
3using System;
4using System.ComponentModel;
5
6namespace NeoPriceConsumer
7{
8 [DisplayName("PriceConsumer")]
9 [ManifestExtra("Author", "Neo Service Layer")]
10 [ManifestExtra("Description", "Sample Oracle Price Consumer")]
11 public class PriceConsumer : SmartContract
12 {
13 // Price storage key
14 private static readonly StorageKey PriceKey = new StorageKey("price");
15
16 // Notification event when price is updated
17 [DisplayName("PriceUpdated")]
18 public static event Action<BigInteger> OnPriceUpdated;
19
20 // Method called by the Oracle Service
21 public static void UpdatePrice(BigInteger price)
22 {
23 // Only allow the Oracle Service to call this method
24 if (!Runtime.CheckWitness(Oracle.OracleAddress))
25 throw new Exception("Unauthorized caller");
26
27 // Store the price
28 Storage.Put(PriceKey, price);
29
30 // Emit event
31 OnPriceUpdated(price);
32 }
33
34 // Get the current price
35 public static BigInteger GetPrice()
36 {
37 return (BigInteger)Storage.Get(PriceKey);
38 }
39 }
40}
3. Query the Oracle Data
Once the oracle is set up and reporting data to your contract, you can query the data:
1// Using Neo SDK to call the consumer contract
2const { rpc, sc } = require('@cityofzion/neon-js');
3
4const rpcClient = new rpc.RPCClient('https://n3seed1.ngd.network:10332');
5const scriptHash = '0x1234567890abcdef1234567890abcdef12345678'; // Your contract hash
6
7async function getNeoPrice() {
8 const result = await rpcClient.invokeFunction(scriptHash, 'GetPrice');
9
10 if (result.state === 'HALT') {
11 const price = parseInt(result.stack[0].value) / 100000000; // Convert back to decimal
12 console.log(`Current Neo price: $${price.toFixed(2)}`);
13 return price;
14 } else {
15 console.error('Failed to get price:', result);
16 return null;
17 }
18}
19
20getNeoPrice();
Advanced Features
Multi-Source Oracles
For critical data points, you can create multi-source oracles that aggregate data from multiple providers:
1{
2 "name": "Neo Multi-Source Price Oracle",
3 "sources": [
4 {
5 "name": "CoinGecko",
6 "url": "https://api.coingecko.com/api/v3/simple/price?ids=neo&vs_currencies=usd",
7 "path": "$.neo.usd",
8 "weight": 1.0
9 },
10 {
11 "name": "Binance",
12 "url": "https://api.binance.com/api/v3/ticker/price?symbol=NEOUSDT",
13 "path": "$.price",
14 "weight": 1.0
15 },
16 {
17 "name": "Huobi",
18 "url": "https://api.huobi.pro/market/detail/merged?symbol=neousdt",
19 "path": "$.tick.close",
20 "weight": 1.0
21 }
22 ],
23 "aggregation": "median", // Options: mean, median, mode, weighted_average
24 "filtering": {
25 "outlier_threshold": 3.0, // Standard deviations for outlier detection
26 "min_sources": 2 // Minimum sources needed for a valid result
27 }
28}
Custom Data Transformations
You can use JavaScript transformations to process data before it's sent to the blockchain:
1// Example transformation function
2function transform(data) {
3 // Convert string to float
4 const price = parseFloat(data);
5
6 // Apply scaling factor for integer representation (8 decimal places)
7 const scaledPrice = Math.round(price * 100000000);
8
9 // Validate the result
10 if (isNaN(scaledPrice) || scaledPrice <= 0) {
11 throw new Error('Invalid price data');
12 }
13
14 return scaledPrice;
15}
Security Considerations
Data Source Security
- Always use HTTPS endpoints
- Store credentials securely using the Secrets Service
- Implement regular rotation of API keys
- Monitor for unusual access patterns
On-chain Security
- Implement data validity checks in your contract
- Use rate limiting for updates
- Verify the Oracle Service signature
- Set appropriate gas limits
API Reference
For a complete API reference, see the Oracle API Documentation.