I am trying to subscribe to a PurchaseMade
event defined in Solidty from the frontend. I am not getting the expected results and need help with what I'm doing wrong.
Environment:
Initialing contract Instance:
export const getContractInstance = () => {
let web3Provider
if (typeof window.web3 !== 'undefined') {
// if metamask is on, web3 is injected...
web3Provider = web3.currentProvider
} else {
// otherwise, use ganache-cli...
web3Provider = new Web3.providers.HttpProvider('http://localhost:8545')
}
web3 = new Web3(web3Provider)
return new web3.eth.Contract(CryptoKpopAbi, CONTRACT_ADDRESS)
}
Subscribing to PurchaseMade event
onBuy = (obj) => {
web3.eth.subscribe("PurchaseMade", {}, () => {
debugger
});
this.ContractInstance.methods.buy(1).send({
from: this.state.currentUserAddress,
gas: GAS_LIMIT,
value: web3.utils.toWei(price.toString(), "ether"),
}).then((receipt) => {
console.log(receipt)
}).catch((err) => {
console.log(err.message)
})
}
I get this warning when I call web3.eth.subscribe
:
Subscription "PurchaseMade" doesn't exist. Subscribing anyway.
I get this error on tx receipt (after send()` succeeds
Uncaught TypeError: Cannot read property 'subscriptionName' of undefined
I used this official doc to setup the subscription
http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html
Thank you in advance!
UPDATE:
Event declaration in contract
event PurchaseMade(uint objId, uint oldPrice, uint newPrice, string objName, address prevOwner, address newOwner);
Event call in contract
function buy(uint _tokenId) payable public {
address prevOwner = ownerOf(_tokenId);
uint currentPrice = tokenIdToPrice[_tokenId];
...
PurchaseMade(_tokenId, currentPrice, newPrice,
tokens[_tokenId].name, prevOwner, msg.sender);
}
Here is a complete create and emit events in Solidity. It creates a transfer event with all the properties. Created a function transferTo which contains logic as well as emits an event Emit an event to client web applications. You have to write a front-end web app to listen to the events using web3 API.
Smart contract events are a way for your contract to communicate that something happened (i.e. there was an event) on the blockchain to your front-end application, which can be 'listening' for specific events and take action when they happen.
Events are not stored in the transaction nor on the blockchain. They are stored within the transaction receipt. TX receipts are stored in the Receipts Trie by the node.
You're attempting to subscribe to the event itself. The API lets you subscribe to an event type and add filters. The valid event types are:
Look at the API documentation for examples on how to use subscribe("logs")
.
The subscribe
API is usually used to listen to events occurring across the blockchain. An easier approach for listening to events for a specific contract is to use events
for the deployed contract (documentation). It's not much different than using subscribe
above, but it already has the contract address and topic filters.
this.ContractInstance.events.PurchaseMade({}, (error, data) => {
if (error)
console.log("Error: " + error);
else
console.log("Log data: " + data);
});
There's one important note, though. With web3 1.0, listening to events is not supported using HttpProvider. You have to use Websockets or IPC.
EDIT - I forgot to mention you can also get the events from the transaction receipt:
contractInstance.events.eventName.returnValues;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With