从前端订阅 Solidity 事件

Max*_*s S 5 ethereum

我正在尝试PurchaseMade从前端订阅Solidty 中定义的事件。我没有得到预期的结果,需要帮助解决我做错了什么。

环境:

  • 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)
}
Run Code Online (Sandbox Code Playgroud)

订阅 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)
    })
}
Run Code Online (Sandbox Code Playgroud)

我打电话时收到此警告web3.eth.subscribe

Subscription "PurchaseMade" doesn't exist. Subscribing anyway.
Run Code Online (Sandbox Code Playgroud)

我在 tx 收据上收到此错误(在 send()` 成功后

Uncaught TypeError: Cannot read property 'subscriptionName' of undefined
Run Code Online (Sandbox Code Playgroud)

我使用这个官方文档来设置订阅

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);
Run Code Online (Sandbox Code Playgroud)

合约中的事件调用

function buy(uint _tokenId) payable public {
  address prevOwner = ownerOf(_tokenId);
  uint currentPrice = tokenIdToPrice[_tokenId];

  ...

  PurchaseMade(_tokenId, currentPrice, newPrice,
    tokens[_tokenId].name, prevOwner, msg.sender);
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*nis 5

您正在尝试订阅事件本身。API 允许您订阅事件类型并添加过滤器。有效的事件类型是:

  • pendingTransactions:接收发送到区块链的新交易的子集(主要用于想要选择他们处理的交易的矿工)
  • newBlockHeaders:当新区块被添加到区块链时接收通知。
  • 同步:节点同步开始/停止时接收通知
  • 日志:接收有关区块链上日志更新的通知。这些是您感兴趣的事件。

看看API文档,了解如何使用示例subscribe("logs")

subscribeAPI通常用来听跨blockchain发生的事件。侦听特定合约的事件的一种更简单的方法是使用events已部署的合约(文档)。和subscribe上面使用没有太大区别,但是它已经有了合约地址和主题过滤器。

this.ContractInstance.events.PurchaseMade({}, (error, data) => {
  if (error)
    console.log("Error: " + error);
  else 
    console.log("Log data: " + data);
});
Run Code Online (Sandbox Code Playgroud)

不过,有一个重要的注意事项。在 web3 1.0 中,不支持使用 HttpProvider 监听事件。您必须使用 Websockets 或 IPC。

编辑 - 我忘了提到您还可以从交易收据中获取事件:

contractInstance.events.eventName.returnValues;
Run Code Online (Sandbox Code Playgroud)