区块链研究实验室-如何让以太坊智能合约与脱链服务互通

您的应用程序不可避免地需要与“现实世界”API进行对话,例如是发送电子邮件,查询更多数据,或充当发起其他处理的信号。 下面让我们探讨如何让以太坊智能合约与脱链服务互通。

概述

简而言之,您可以在处理事务时使智能合约发出事件。一旦事务被挖掘,事件数据就可以读取。在下图中,您可以看到您的DApp发出的事件可以从您的API的任何服务中检索。

目前有两种方法可以获取事件数据:

目前有两种方法可以获取事件数据: 

选项1:使用getTransactionReceipt

选项2:为事件注册监听器

您可以使用选项1来获取事件数据,但是可能会存在潜在问题,因为在区块被挖掘之前收据是空的。你可以提出调查,但这很难做到。

另外,根据网络流量和gasPrice设置,交易可能长时间不会被打包。请注意,事件只有在被挖掘成区块后才会被传播。这意味着可以为任何一个区块调用多个事件。  

solidity事件

在solidity里创建事件需要两个步骤:定义事件,发出事件。

注意事件Transfer是如何在第5行创建的,然后在函数传输中使用它发出Transfer事件(第10行)。 但会告诉你如何使用一个事件,如果我们用0x123调用传递函数,并从0x4444的地址发送1以太,则事件触发传输事件并应返回[0x4444,0x123,BigNumber(1以太)]。

监听事件

以太坊实现了他们的JSON RPC规范,但任何人都可以用他们选择的语言实现自己的库。 我们将使用Truffle和原始web3 Javascript API。 监听事件的一般流程如下:

1、加载合同组件

2、配置web3和使用truffle提供程序

3、识别网络id

4、从合同组件中获取正确的合同地址

5、获取JavaScript合约实例

6、使用可选配置调用contractInstace.NAME_OF_EVENT

下面我们有3个样本使用Truffle,Web3在1.0 beta之前,Web3在1.0 beta之后。  

Truffle是web3的一个很好的包装器,它提供了一些便利功能,使用更加轻松。 看一下下面的代码示例:

const Web3 = require('web3') // Web3 0.20.4 or web3 1 beta
const truffleContract = require("truffle-contract")
const contractArtifact = require('./build/contracts/TutorialToken.json')

const providerUrl = 'http://localhost:8545'
const provider = new Web3.providers.HttpProvider(providerUrl)

const contract = truffleContract(contractArtifact)
contract.setProvider(provider)

// dirty hack for [email protected] support for localhost testrpc, see https://github.com/trufflesuite/truffle-contract/issues/56#issuecomment-331084530
if (typeof contract.currentProvider.sendAsync !== "function") {
  contract.currentProvider.sendAsync = function() {
      return contract.currentProvider.send.apply(
        contract.currentProvider,
            arguments
      );
    };
  }

contract.deployed()
  .then(contractInstance => {
    const event = contractInstance.Transfer(null, {fromBlock: 0}, (err, res) => {
      if(err) {
        throw Error(err)
      }
    })
    event.watch(function(error, result){
      if (error) { return console.log(error) }
      if (!error) {
        // DO ALL YOUR WORK HERE!
        let { args: { from, to, value }, blockNumber } = result
        console.log(`----BlockNumber (${blockNumber})----`)
        console.log(`from = ${from}`)
        console.log(`to = ${to}`)
        console.log(`value = ${value}`)
        console.log(`----BlockNumber (${blockNumber})----`)
      }
    })
  })
  .catch(e => {
    console.error('Catastrophic Error!')
    console.error(e)
  })

前9行需要一些模块,并设置truffle和web3能够正常网络通信。 第12-19行作为hack使其与web3一起使用,可以忽略。 工作从第21行开始,带有contract.deployed()。 这是一个很好的truffle辅助函数,可以从创建并保存到./build/contracts的工件中选择正确的合同地址。 返回contractInstance(第23行)后,我们通过调用contractInstance.NAME_OF_EVENT来“创建”该事件。 存在更多选项,可在此处找到。 我从0块中选择,因为它是我们自己的testrpc。 对于您的合同,最好选择更接近合同创建时的块编号。

Raw Web3(0.20.4及以下)

对于第二个示例,我们将直接使用Web3。 除了上一个示例中的hack之外,代码流程类似。

const Web3 = require('web3') // Works with web3 0.20.4
const contractArtifact = require('./build/contracts/TutorialToken.json')

const web3 = new Web3()
const providerUrl = 'http://localhost:8545'
const provider = new Web3.providers.HttpProvider(providerUrl)
web3.setProvider(provider)

const networkId = web3.version.network
const contractAddr = contractArtifact.networks[networkId].address
const TutorialToken = web3.eth.contract(contractArtifact.abi, contractAddr)
const contract = TutorialToken.at(contractAddr)

const event = contract.Transfer()
event.watch(function(error, result){
    if (error) { return console.error(error) }
      let { args: { from, to, value }, blockNumber } = result
      console.log(`----BlockNumber (${blockNumber})----`)
      console.log(`from = ${from}`)
      console.log(`to = ${to}`)
      console.log(`value = ${value}`)
      console.log(`----BlockNumber (${blockNumber})----`)
  });

最重要的区别是第9-12行,我们手动从组件中抓取正确的网络。 我们没有很好的truffle.deployed功能来实现这一步。 现在我们在truffle示例中执行与之前相同的操作,并通过调用contract.NAME_OF_EVENT来创建事件。 在这个版本中我没有放一个块号,但是你可以传递与truffle版相同的东西。

Raw Web3 1.0.0 beta

Web3确实为API带来了大量更改。 一个重大变化是我们必须使用webSockProvider来注册事件而不是httpProvider。

总结

您应该了解如何将您的offchain服务连接到onchain事件。 这意味着您现在可以将区块链集成到现有基础架构中。

本文转载公众号:区块链研究实验室(bc-tech-lab)

猜你喜欢

转载自blog.csdn.net/willam1/article/details/86636432