请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

「区块链研究实验室」以太坊DApp实战-足球投注app(二)

2018-5-23 18:59| 发布者: 小星云小幸运| 查看: 591| 评论: 0|原作者: 区块链研究实验室

摘要: 文章介绍了以太坊DApp实战-足球投注app应用

开始使用Oraclize API

为了让合约使用Oraclize服务,它需要继承usingOraclize合约。用户可以在找到该合约。

usingOraclize合约可以代替OraclizeI和OraclizeAddrResolverI合约。事实上,usingOraclize使得OraclizeI和OraclizeAddrResolverI合约的调用

变得方便,也就是说,它提供了更简单的API。也可以直接调用OraclizeI和OraclizeAddrResolverI合约。读者可以学习这些合约的源代码以发现所有可用API,本书中,我们只学习最必需的那些。

下面来看设定proof类型、设定proof存储位置、进行查询、获取查询费用等的方法。

1.设置证明类型和存储位置

无论是否需要来自TLSNotary的proof,必须在发出查询之前指定proof类型和proof存储位置。

如果不需要proof,就把下面的代码放入合约:

「区块链研究实验室」以太坊DApp实战-足球投注app(二)

如果需要proof,就把下面的代码放入合约:

「区块链研究实验室」以太坊DApp实战-足球投注app(二)

目前,proofStorage_IPFS是唯一可用的proof存储位置,也就是说,TLSNotary proof只存储在IPFS中。

每次只能执行这些方法中的任意一个,例如在constructor中或者在其他任何时间(比如只需要某些特定查询的proof)。

2.发送查询

为了向Oraclize发送一个查询,需要调用oraclize_query函数。这个函数至少需要两个实参,即数据源和给定数据源的输入值。数据源实参

不区分大小写。

oraclize_query函数的一些基础示例如下:

「区块链研究实验室」以太坊DApp实战-足球投注app(二)

上述代码的执行过程如下:

  • 如果第一个实参是字符串,就假定它是数据源,第二个实参就假定为数据源的输入条件。在第一个调用中,数据源是WolframAlpha,我们向它发送的查询是0和100之间的随机数。
  • 在第二个调用中,向第二个实参中所示的URL发出HTTP GET请求。
  • 在第三个调用中,从IPFS获取QmdEJwJG1T9rzHvBD8i69HHuJaRgXRKEQCP7Bh1BVttZbU文件的内容。
  • 如果数据源之后的两个连续实参是字符串,就假定它是POST请求。在最后一个调用中,发出HTTP POST请求到进行支付。POST请求内容是第三个实参中的字符串。Oraclize十分智能,能够检测基于字符串格式的content-type标头。

预约查询

如果想让Oraclize在未来某一预订时间执行查询,就指定从当前时间算起的延迟(以秒计算)作为第一个实参。示例如下:

「区块链研究实验室」以太坊DApp实战-足球投注app(二)

Oraclize将在看到上述查询60s之后进行查询。所以,如果第一个实参是数字,就假定我们在预约查询。

自定义gas

就像其他任何交易一样,从Oraclize到_callback函数的交易要花费gas,即需要向Oraclize支付gas费用。Oraclize_query进行查询收取的以

太币还用于在调用_callback函数时提供gas。调用_callback函数时,Oraclize默认提供200000个gas。

这个返回的gas费用实际上受用户控制,因为用户编写的_callback等方法中的代码可以预估费用。所以当用Oraclize进行查询时,还可以在_callback交易上指定gasLimit应当是多少。但需要注意的是,因为是由Oraclize发送交易,所以没有花费的gas将被返还给Oraclize,而非用户。

如果200000 gas(默认值,也是最小值)不够,可以指定一个更大的gasLimit,代码如下:

「区块链研究实验室」以太坊DApp实战-足球投注app(二)

可以看到,如果最后一个实参是数字,就假定它是自定义的gas。在程序代码中,Oraclize将对回调函数交易使用一个500000的gas上限,

而非200000。因为我们让Oraclize提供gas,所以Oraclize在调用oraclize_query时将扣除更多以太币(根据需要多少gas)。

回调函数(callback function)

一旦结果准备好了,Oraclize将把交易发送回合约地址,并调用如下三个方法中的一个:

  • 对于每个查询来说,_callback(bytes32 myid,stringresult)“.”Myid都是一个独特的ID。这个ID由oraclize_query方法返回。如果合约里有多个oraclize_query调用,则将这用于匹配该结果的查询。
  • 如果需要TLSNortary的proof,则结果为_callback(bytes32 myid,string result,bytes proof)。
  • 如果没有其他方法,回退函数是function()。下面是_callback函数的一个例子:
「区块链研究实验室」以太坊DApp实战-足球投注app(二)

解析助手

HTTP请求返回的结果可以是HTML、JSON、XML或二进制等格式。在Solidity中,解析结果是很困难的,且代价很高。Oraclize提供了

解析助手,在服务端上处理解析,最终得到的结果就是用户需要的那部分。

  • 为了让Oraclize解析结果,用户需要把URL和下面某一个解析助手(Parsing helpers)“打包”:
  • xml(..)和json(..)助手让Oraclize只返回部分JSON或者用XML解析的返回值,例如:
  • 为了得到全部返回值,使用带有api.kraken.com/0/public/Ticker?pair=ETHUSD URL实参的URL数据源。
  • 如果只想要最终价字段,需要使用JSON解析调用json(api.kraken.com/0/public/Ticker?pair=ETHUSD).result.XETHZUSD.c.0。
  • html(..).xpath(..)助手用于HTML scraping,仅需指定想用作xpath(..)实参的XPATH,例如:
  • 为了抓取一个特定tweet的文本,使用html().xpath(//*[contains(@class,'tweettext')]/text())。
  • binary(..)助手用于获得诸如证书文件的二进制文件,例如证书文件:
  • 为了抓取二进制文件的一部分,可以使用slice(offset,length)。其中第一个参数是位移,第二个参数是所需的slice长度(二者都用字节
  • 表示)。
  • 示例:从一个二进制CRL中只抓取开头300个字节,用binary().slice(0,300)。二进制助手必须和slice选项同时使用,且只接受二进制文件(不接受编译文件)。

获取查询价格

如果在实际查询之前想知道查询需要多少费用,可以使Oraclize.getPrice()函数获取所需的wei的数量。第一个实参是数据源,第二个实参是可选项,即自定义gas。

一个常见的使用示例是,当以太币余额不足以进行查询时,通知客户端向合约添加以太币。