从前端订阅 Solidity 事件
Subscribing to a Solidity event from frontend
我正在尝试从前端订阅在 Solidty 中定义的 PurchaseMade
事件。我没有得到预期的结果,需要帮助解决我做错的事情。
环境:
- ganache-cli,松露
- web3.js, React.js
初始化合约实例:
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)
}
正在订阅 PurchaseMade 事件
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)
})
}
我在调用 web3.eth.subscribe
时收到此警告:
Subscription "PurchaseMade" doesn't exist. Subscribing anyway.
我在 tx 收据上收到此错误(在 send()` 成功后
Uncaught TypeError: Cannot read property 'subscriptionName' of undefined
我使用这个官方文档来设置订阅
http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html
提前致谢!
更新:
合约中的事件声明
event PurchaseMade(uint objId, uint oldPrice, uint newPrice, string objName, address prevOwner, address newOwner);
合约中的事件调用
function buy(uint _tokenId) payable public {
address prevOwner = ownerOf(_tokenId);
uint currentPrice = tokenIdToPrice[_tokenId];
...
PurchaseMade(_tokenId, currentPrice, newPrice,
tokens[_tokenId].name, prevOwner, msg.sender);
}
您正在尝试订阅活动本身。 API 允许您订阅事件类型并添加过滤器。有效的事件类型是:
- pendingTransactions:接收发送到区块链的新交易的子集(主要用于想要选择他们处理的交易的矿工)
- newBlockHeaders:当新区块被添加到区块链时接收通知。
- syncing:节点同步时收到通知starts/stops
- logs:接收有关区块链日志更新的通知。这些是您感兴趣的活动。
查看 API documentation 以获取有关如何使用 subscribe("logs")
的示例。
subscribe
API 通常用于侦听跨区块链发生的事件。监听特定合约事件的更简单方法是对已部署合约 (documentation) 使用 events
。它与上面使用 subscribe
没有太大区别,但它已经具有合约地址和主题过滤器。
this.ContractInstance.events.PurchaseMade({}, (error, data) => {
if (error)
console.log("Error: " + error);
else
console.log("Log data: " + data);
});
不过,有一点很重要。使用 web3 1.0,listening to events is not supported using HttpProvider。您必须使用 Websockets 或 IPC。
编辑 - 我忘了说您也可以从交易收据中获取事件:
contractInstance.events.eventName.returnValues;
我正在尝试从前端订阅在 Solidty 中定义的 PurchaseMade
事件。我没有得到预期的结果,需要帮助解决我做错的事情。
环境:
- ganache-cli,松露
- web3.js, React.js
初始化合约实例:
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)
}
正在订阅 PurchaseMade 事件
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)
})
}
我在调用 web3.eth.subscribe
时收到此警告:
Subscription "PurchaseMade" doesn't exist. Subscribing anyway.
我在 tx 收据上收到此错误(在 send()` 成功后
Uncaught TypeError: Cannot read property 'subscriptionName' of undefined
我使用这个官方文档来设置订阅
http://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html
提前致谢!
更新:
合约中的事件声明
event PurchaseMade(uint objId, uint oldPrice, uint newPrice, string objName, address prevOwner, address newOwner);
合约中的事件调用
function buy(uint _tokenId) payable public {
address prevOwner = ownerOf(_tokenId);
uint currentPrice = tokenIdToPrice[_tokenId];
...
PurchaseMade(_tokenId, currentPrice, newPrice,
tokens[_tokenId].name, prevOwner, msg.sender);
}
您正在尝试订阅活动本身。 API 允许您订阅事件类型并添加过滤器。有效的事件类型是:
- pendingTransactions:接收发送到区块链的新交易的子集(主要用于想要选择他们处理的交易的矿工)
- newBlockHeaders:当新区块被添加到区块链时接收通知。
- syncing:节点同步时收到通知starts/stops
- logs:接收有关区块链日志更新的通知。这些是您感兴趣的活动。
查看 API documentation 以获取有关如何使用 subscribe("logs")
的示例。
subscribe
API 通常用于侦听跨区块链发生的事件。监听特定合约事件的更简单方法是对已部署合约 (documentation) 使用 events
。它与上面使用 subscribe
没有太大区别,但它已经具有合约地址和主题过滤器。
this.ContractInstance.events.PurchaseMade({}, (error, data) => {
if (error)
console.log("Error: " + error);
else
console.log("Log data: " + data);
});
不过,有一点很重要。使用 web3 1.0,listening to events is not supported using HttpProvider。您必须使用 Websockets 或 IPC。
编辑 - 我忘了说您也可以从交易收据中获取事件:
contractInstance.events.eventName.returnValues;