Random Number Generation Service
Overview
The Random Number Generation Service provides secure, verifiable random numbers for Neo N3 smart contracts through a Trusted Execution Environment (TEE). This service is ideal for applications that require unpredictable randomness like gaming, gambling, NFT distribution, and fair selection processes.
Key Features
Verifiable Randomness
All random numbers come with cryptographic proof that they were generated fairly and were not manipulated.
TEE Security
Random number generation occurs in a Trusted Execution Environment (TEE), ensuring that not even the service operator can predict or manipulate the results.
On-chain Verification
Generated numbers include verification data that can be checked on-chain to confirm their authenticity and fairness.
Direct Contract Integration
Random numbers can be delivered directly to smart contracts through our callback mechanism.
Multiple Output Formats
Request integers within ranges, boolean values, or byte arrays depending on your application's needs.
Subscription Model
Set up recurring random number deliveries for applications that need regular randomness, like lottery systems.
How It Works
Architecture
The Random Number Generation Service uses a multi-layered approach to ensure entropy and verifiability:
- Request Intake: Your application or smart contract requests a random number through our API or via an on-chain event.
- TEE Processing: The request is processed in a Trusted Execution Environment where random data is generated using hardware-based entropy sources.
- Cryptographic Proof: The random number is signed with the TEE's private key, creating a verifiable attestation.
- Delivery: The random number and its proof are delivered to your application or smart contract.
- Verification: The recipient can verify the random number's authenticity using our on-chain verification contract.

Usage Examples
Example 1: Basic Random Number Generation
Request a random number between 1 and 100:
// JavaScript example using the Neo Service Layer SDK import { RandomService } from 'neo-service-layer-sdk'; // Initialize the service with your API key const randomService = new RandomService({ apiKey: 'your-api-key' }); // Generate a random number between 1 and 100 const result = await randomService.generateRandomNumber({ min: 1, max: 100, // Optional metadata for your application metadata: { purpose: 'lottery-draw', sessionId: 'abc123' } }); console.log('Random number:', result.number); console.log('Verification proof:', result.proof);
Example 2: Smart Contract Integration
Request a random number directly to your smart contract using the callback pattern:
// NEO•ONE example of a lottery contract import { SmartContract, SerializableValueObject, Address, constant, createEventNotifier, Fixed, MapStorage, Deploy } from '@neo-one/smart-contract'; interface RandomNumberRequest { readonly requestId: string; readonly callbackContract: Address; readonly callbackMethod: string; readonly min: number; readonly max: number; } const notifyRandomNumberRequest = createEventNotifier<RandomNumberRequest>( 'RandomNumberRequest' ); export class LotteryContract extends SmartContract { private readonly participants = MapStorage.for<string, Address>(); private readonly ticketCount = MapStorage.for<Address, number>(); private readonly randomOracleAddress = Address.from('NXV7ZhHiyMU44Xyt5dGmQQNrwRnxZqTvex'); @constant public get participantCount(): number { return this.participants.size; } public buyTicket(): boolean { const participant = this.transaction.sender; const ticketId = this.participantCount.toString(); // Store participant information this.participants.set(ticketId, participant); const currentTickets = this.ticketCount.get(participant) || 0; this.ticketCount.set(participant, currentTickets + 1); return true; } @constant public getParticipant(ticketId: string): Address { return this.participants.get(ticketId); } public selectWinner(): void { // Ensure there are participants if (this.participantCount === 0) { throw new Error('No participants in the lottery'); } // Create request ID (should be unique per request) const requestId = this.transaction.hash.toString(); // Request a random number from the oracle notifyRandomNumberRequest({ requestId, callbackContract: this.address, callbackMethod: 'processWinner', min: 0, max: this.participantCount - 1 }); } // Callback method that will be invoked by the random service public processWinner(requestId: string, randomIndex: number, proof: string): void { // Verify the caller is the oracle if (!this.transaction.sender.equals(this.randomOracleAddress)) { throw new Error('Unauthorized caller'); } // Get the winning ticket ID and participant const winningTicketId = randomIndex.toString(); const winner = this.getParticipant(winningTicketId); // Process winner (transfer prizes, etc.) // ... } }
Example 3: Subscribing to Random Numbers
Set up a subscription to receive random numbers at regular intervals:
// JavaScript example using the Neo Service Layer SDK import { RandomService } from 'neo-service-layer-sdk'; // Initialize the service with your API key const randomService = new RandomService({ apiKey: 'your-api-key' }); // Create a subscription for daily random numbers const subscription = await randomService.createSubscription({ // Generate a random number between 1-1000 daily schedule: '0 0 * * *', // Cron syntax: at midnight every day configuration: { min: 1, max: 1000 }, // Where to send the random numbers destination: { type: 'webhook', url: 'https://your-app.com/api/random-callback' }, // Optional metadata metadata: { name: 'Daily Lottery Draw', description: 'Random number for selecting daily winner' } }); console.log('Subscription created:', subscription.id);
Verifying Random Numbers
To verify that a random number was generated fairly, you can use our verification contract or SDK:
// JavaScript example of verifying a random number import { RandomService } from 'neo-service-layer-sdk'; // Initialize the service const randomService = new RandomService({ apiKey: 'your-api-key' }); // Verify a random number using its proof const isValid = await randomService.verifyRandomNumber({ randomNumber: 42, proof: 'proof-data-from-generation-response', requestId: 'original-request-id' }); if (isValid) { console.log('Random number verified successfully!'); } else { console.error('Random number verification failed!'); }
For on-chain verification, you can call our verification contract directly:
// NEO•ONE example of calling the verification contract import { SmartContract, u, Address } from '@neo-one/smart-contract'; export class MyContract extends SmartContract { private readonly randomVerifierAddress = Address.from('NR19TBVdRfegCHf54UhdJRGkFagvDN7XM9'); public verifyRandomNumber( randomNumber: number, proof: string, requestId: string ): boolean { // Create a call to the verification contract const verifierContract = SmartContract.for<{ verify: (randomNumber: number, proof: string, requestId: string) => boolean; }>(this.randomVerifierAddress); // Call the verify method return verifierContract.verify(randomNumber, proof, requestId); } }
Security Considerations
Entropy Sources
Our random number generation relies on multiple sources of entropy:
- Hardware-based random number generators in the TEE
- Environmental entropy from system timing variations
- Transaction-specific data for additional unpredictability
Front-Running Protection
To prevent front-running attacks (where observers attempt to predict or manipulate outcomes), the random service implements:
- Commit-reveal schemes for on-chain randomness
- Time-delayed publication of random values
- Request-specific seeds that cannot be reused
Auditability
The random number generation process is designed to be auditable:
- All requests and responses are logged with timestamps
- TEE attestation documents are available for verification
- The verification contract's code is open source and audited
Integration with Other Services
Functions Service
You can use the Random Number Generation Service within your Functions:
// Example function that uses the random service module.exports = async function(context) { // Access the random service from the context const { random } = context.services; // Generate a random number const result = await random.generate({ min: 1, max: 100 }); return { randomNumber: result.number, proof: result.proof }; };
Automation Service
You can trigger random number generation based on time or events:
// Example automation configuration { "triggers": [ { "type": "schedule", "schedule": "0 12 * * *" // Every day at noon } ], "action": { "type": "random", "configuration": { "min": 1, "max": 1000, "destination": { "type": "contract", "scriptHash": "0x7a16a1f5c40e69790333f3bfe7e4325a08cc2f79", "operation": "processDailyDraw" } } } }
API Reference
For a complete API reference, see the Random Service API documentation.
Key Endpoints
POST /v1/random/generate
- Generate a random numberPOST /v1/random/verify
- Verify a random number and its proofPOST /v1/random/subscriptions
- Create a subscriptionGET /v1/random/subscriptions
- List your subscriptionsGET /v1/random/history
- View your random number request history
Pricing
The Random Number Generation Service is priced based on the number of random values generated:
Plan | Random Values | Price |
---|---|---|
Free Tier | Up to 1,000 / month | Free |
Standard | Up to 100,000 / month | 0.01 GAS per request |
Enterprise | Unlimited | Custom pricing |
See the Pricing page for more details.
Next Steps
Examples
Explore complete examples of random number generation in different scenarios.
View examples →API Documentation
View the complete API reference for the Random Number Service.
View API documentation →Integration Tutorials
Follow step-by-step tutorials for integrating random numbers in your applications.
View tutorials →