I have the following (very simple) oracle contract. All I want it to do is manage data on the chain that is returned by an open source API - I'll use this data in another contract. I am able to call the methods of my contract without any issue using web3js, but I am unable to listen for events on a socket. I should be seeing console.log('Event firing ', event)
output something, but I do not. If helpful, I am running ganache and truffle locally to host the contract
When I hit the http://localhost:3000/api/oracle
endpoint, I get the following (source code below the output). Can someone help me understand why I'm not capturing the events correctly?
[0] 9:36:44 AM - Found 0 errors. Watching for file changes.
[1] Running on 3000 ⚡
[1] Endpoint called
[1] Contract response Done
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
contract SnapshotOracle {
// Contract owner
address public owner;
string[] public voters;
// Callback function
event CallbackGetVotes(address owner);
constructor() {
owner = msg.sender;
}
// This is called first, which emits an event
// that fetches new data
function updateVotes() public returns (string memory) {
emit CallbackGetVotes(owner);
return "Done";
}
// Once the data is fatched by the service,
// setVotes is called to set that data
function setVotes(string[] memory _voters) public {
require(msg.sender == owner);
voters = _voters;
}
// Finally, getVotes is called to get the new data
function getVotes() public view returns (string[] memory) {
return voters;
}
}
// Simple Node oracle service to interact with oracle contract
import express, { Express, Request, Response } from 'express';
import bodyParser from 'body-parser';
import helmet from 'helmet';
import dotenv from 'dotenv';
import Web3 from 'web3'
import OracleContract from './contracts/SnapshotOracle.json'
import { AbiItem } from 'web3-utils'
dotenv.config();
const PORT = process.env.PORT || 3000;
const app: Express = express();
app.use(helmet());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Web socket to contract
const CHAIN_PORT = '7545'
const ORACLE_ADDR = '0x05dbB4b1C895C593b66686b5234D3cD80D18E460'
const web3 = new Web3(`ws://127.0.0.1:${CHAIN_PORT}`)
const oracleContract = new web3.eth.Contract(OracleContract.abi as AbiItem[], ORACLE_ADDR)
web3.eth.getAccounts((err, accounts) => {
const a = oracleContract.events.CallbackGetVotes({owner: accounts[0]})
.on('data', (event: any) => {
console.log('Event firing ', event)
// TODO: Run API Request
// TODO: Save result of API request to contract state
})
})
app.get('/api/oracle', (req: Request, res: Response) => {
const web3 = new Web3(`http://127.0.0.1:${CHAIN_PORT}`)
const oracleContract = new web3.eth.Contract(OracleContract.abi as AbiItem[], ORACLE_ADDR)
console.log('Endpoint called')
web3.eth.getAccounts(async (err, accounts) => {
const t = await oracleContract.methods.updateVotes().call({owner: accounts[0]})
console.log('Contract response', t)
setTimeout(async () => {
const votes = await oracleContract.methods.getVotes().call()
res.send(votes)
}, 3000)
})
});
app.listen(PORT, () => console.log(`Running on ${PORT} ⚡`));