主页
欢迎阅读Provable文档,该文档的内容主要可以分为以下这几部分:
1.背景:Provable预言机模型背后的原理
2.普遍概念:主要的概念背后的Provable
3.数据源:关于Provable支持的数据源的类型信息
4.集成:如何将区块链应用程序与Provable集成
5.开发工具:用以辅助开发集成Provable的智能合约的工具列表
6.安全性深入研究:Provable的真实性证明是如何工作的
7.定价:生产使用的定价模型的信息
8.教程:关于集成Provable的教程
背景
Provable是一个面向智能合约和区块链应用的领先的预言机服务,每天在以太坊、Rootstock、R3 Corda、Hyperledger Fabric和EOS等平台上,处理数千个请求。
在区块链世界中,预言机是提供数据的一方。对这些数据的需求,来源于如下真实案例:
区块链上的应用程序,比如比特币脚本和智能合约无法直接访问和获取它们所需要的数据:资产和金融应用的价格提要;点对点保险的与天气相关的信息;赌博的随机数生成。
但是,如果依赖于一个新的可信中介,也就是预言机,那这将违背区块链应用程序的安全性和低信任模型:这就是区块链应用程序变得有趣和有用的首要原因。
有一种解决方案是接受来自多个不受信任或部分受信任方的数据输入,然后只在多个不受信任的数据输入方,提供了相同的答案,或提供了满足某些约束条件的答案的前提之下,才执行使用该数据的操作。这一类型的系统可被认为是分权式预言机系统。但是这一类型的系统有严重的局限性:
1.它需要一个预定义的数据格式标准
2.它本质上是低效的:所有参与方都需要一笔费用,而且对于每一个请求,在得到足够数量的答案之前都需要等待一段时间。
反之,Provable这个解决方案是,证明从原始数据源获取的数据是真实的、未被篡改的。这是通过将返回的数据与一个称为真实性证明的文档一起完成的。真实性证明可以建立在不同的技术之上,比如可审计的虚拟机和可信的执行环境。
在真实性证明部分提供了Provable真实性证明的更详细的阐述。
这个解决方案优雅地解决了预言机的问题:
1. 区块链应用程序的开发者,以及区块链应用程序的用户,不必信任Provable;安全模型得到维护。
2. 数据提供者不必为了兼容区块链协议而修改他们的服务。智能合约可以直接访问Web网站或APIs的数据。
Provable引擎可以非常简易地,与不同协议的私有区块链和公有区块链实例相集成。
在构建服务时,Provable团队已经意识到真实性证明的概念比最初设想的适用性要广泛得多。例如,Provable随机数据源甚至可以被传统的赌博应用程序使用,以确保用户操作的持续公平性。
普遍概念
Provable可以与许多区块链协议集成,而且其服务对非区块链应用程序也是有用的和可访问的。在下一部分中,我们将解释适用于所有集成的普遍概念。
Provable引擎
Provable引擎可以为基于区块链和非基于区块链的应用程序均提供服务。在内部复制一个“If This Then That”的逻辑模型。这意味着,如果满足其他一些给定的条件,它将执行给定的操作集。例如,它可以重复验证一个条件,并且只有在条件满足时才返回数据或执行操作。这种灵活性使得Provable引擎能够在许多不同的方式和上下文中被利用,甚至可以在区块链上下文之外。
通过本地区块链集成或HTTP API向Provable发出的有效数据请求,应当指定以下参数:
1.数据源的类型
2.具体的查询
3.一个真实性证明类型,可选
数据源类型
数据源是受信任的数据提供者。它可以是一个网站或web API,如Reuters、Weather.com、BBC.com,或者运行在硬件中的、强制的可信执行环境(TEE)上的安全应用程序,或者运行在云提供商中的可审计、锁定的虚拟机实例。Provable目前提供以下类型的原生数据源:
1.URL:允许访问任何网页或HTTP API端点
2.WolframAlpha:允许本机访问WolframAlpha计算引擎
3.IPFS:提供对存储在IPFS文件中的任何内容的访问
4.随机:提供来自安全应用程序的未被篡改的随机字节运行在账本Nano S上。
5.计算:提供任意计算的结果
此外,还有一些元数据源,如:
1.嵌套:允许组合不同类型的数据源或使用同一数据源的多个请求,并返回唯一的结果
2.标识:它返回查询
3.解密:它解密一个加密到Provable私钥的字符串
查询
一个查询是一个参数数组,为了完成一个特定的数据源类型请求,需要对其进行评估:
query: [ parameter_1, parameters_2, ...];
第一个参数是主要参数,它通常是强制性的。例如,对于URL数据源类型,第一个参数是资源所在的预期URL。如果只有第一个参数存在,那么URL数据源就假定请求为HTTP GET。第二个参数是可选的,它应该包含HTTP POST请求的数据有效参数。
可能需要解析查询的中间结果:例如,在JSON API响应中提取精确的字段。因此,查询还可以指定要应用的解析助手程序。
解析助手
Provable提供了JSON、XML、XHTML和二进制的解析助手。下面是例子:
1.JSON解析:要从JSON文档中提取特定元素的值,可以使用我们内置的JSON解析器。一个示例使用案例,从Kraken API中提取ETH/USD价格字段,将其作为JSON文档提供,是通过使用helper将API端点包围起来,如下所示:
json(https://api.kraken.com/0/public/Ticker?pair=ETHUSD).result.XETHZUSD.c.0.
2.XML解析器:要从XML文档中提取特定元素的值,可以使用我们内置的XML解析器。从作为XML文档提供服务的API中提取柴油价格的一个示例使用案例是,使用如下的助手围绕有问题的API端点:
xml(https://www.fueleconomy.gov/ws/rest/fuelprices).fuelPrices.diesel
3.HTML解析器:对HTML抓取很有用。所需的XPATH可以指定为XPATH(..)的参数,如示例所示:
html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())
4.Binary Helper:使用slice(offset,length)操作符提取二进制中间结果的部分非常有用。第一个参数是预期的偏移量,第二个参数是返回片的长度。例如,
binary(https://www.sk.ee/crls/esteid/esteid2015.crl).slice(0,300)
返回链接的证书撤销列表中第一个证书的原始字节。Binary helper必须与slice选项一起使用,并且只接受原始的二进制输入。
注意:Provable 'json()' 和 'xpath()' helpers分别支持JSONPATH和XPATH标准。JSONPATH实现是与FlowCommunications JSONPATH 0.3.4完全兼容的,可以通过这个外部网站进行轻松的测试。我们使用的XPATH实现与XPATH 1.0标准是完全兼容的。
请注意,Provable测试查询页面工具对于利用解析帮助程序测试任何Provable查询都很有用。更多细节请参见“开发工具测试查询”一节。
真实性证明
Provable的目的是充当一个不可信的中介。可选地,Provable请求可以指定一个真实性证明。并非所有的证明都与所有数据源类型兼容。关于真实性证明的更多细节可以在“安全性深入研究”这一部分中找到。
在处理真实性证明时,总是使用https://调用,否则您的请求可能会在过程中被篡改(MITM攻击),并且无法检测到这种攻击。
如果“Provable”由于技术原因无法生成真实性证明,在大多数情况下,它将返回没有要求的证明的结果。由开发人员决定如何在其应用程序中处理这种情况:Provable建议丢弃结果并创建一个新的查询。
数据隐私
某些环境,例如公有区块链上的智能合约,可能需要一定程度的隐私来保护数据免受公众审查。开发人员可以通过使用Provable公钥加密整个查询或其部分参数来生成加密的Provable查询。更多信息可以在加密查询部分找到。
数据源
下面列出的是您在使用预言机服务时可以选择的数据源。
请注意数据源选择是不区分大小写的。
URL
URL数据源类型允许访问因特网上的任何API或web页面。它同时支持HTTP GET和HTTP POST请求。如果在查询中只指定了一个参数,该服务将默认执行HTTP GET请求。如果指定了第二个参数,则服务将执行HTTP POST请求,将第二个参数作为请求的参数数据进行发布。注意,如果第二个参数是有效的JSON,那么它将作为JSON发布。URL数据源类型支持TLSNotary证明和Android证明。更高级的HTTP功能,如基本身份验证或OAuth,可以通过利用“计算”这种数据源类型来构建。
由于可以证明是一个远程服务,它要求“URL”数据源也可以远程访问。如果开发人员可能希望使用一个API只能本地网络,他们可能会使用“localtunnel”工具,通过npm的揭露他们的本地端口,通过一个公开访问的URL(这是作为查询参数,在localhost:8080或127.0.0.1)。有关该实用程序的更多信息,请访问:https://localtunnel.github.io/www/
WolframAlpha
WolframAlpha数据源类型支持直接访问WolframAlpha知识引擎API。此数据源期望将应该传递给WolframAlpha的字符串作为唯一参数。它将以字符串的形式返回结果。
开发人员应该通过Provable的测试页面来测试查询的有效性,以确保您的语法对Wolfram的引擎有意义。
这个数据源不支持真实性证明,因为返回整个API响应违背了WolframAlpha服务条款。因此,Provable建议仅在测试时使用此数据源类型。
IPFS
IPFS数据源类型可用于检索IPFS网络上文件的内容。
该数据源期望查询中的IPFS multihash作为唯一参数。例如,文件
QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o
将返回“hello world\n”。
如果Provable未能在20秒内获取IPFS内容,则请求将失败。
计算
计算数据源通过利用沙箱Amazon Web服务虚拟机,支持应用程序或脚本的可审计执行。
应用程序必须在标准输出上打印计算结果作为退出前的最后一行。结果最长可达2500个字符。执行上下文必须由Dockerfile来描述,在这里构建和运行它应该直接启动主应用程序。当前Provable只提供一种类型的可审核实例:t2.micro实例。Dockerfile初始化和应用程序执行应尽快终止,因为执行时间上限为5分钟。(当前用于计算ds的Docker版本是1.12.1)
开发人员可以通过创建存档并将其上传到IPFS,将应用程序二进制文件或脚本、它的依赖关系和Dockerfile发送给可验证的应用程序。查询期望该归档文件的IPFS multihash作为第一个参数,而以下参数将作为环境变量传递给执行环境,使应用程序可以访问它们。
Provable可能使用Dockerfile的MAINTAINER字段中指定的电子邮件,作为任何问题出现时的联系信息。
Dockerfile必须在archive.zip的根目录下,而非子目录下。
随机
这里描述的设计防止了Provable篡改来自可信执行环境(TEE)的随机结果,并保护用户免受许多攻击向量的攻击。
真实性证明,连同结果,可以很容易地被验证,不仅在链下,甚至任何可靠的合约接收他们。这里给出的示例展示了如何集成验证过程,丢弃任何真实性证明未通过验证过程的随机结果。
随机数据源利用分类帐证明来证明生成的随机性的起源是一个真正安全的分类帐设备。
这种安全地将脱离链的随机性输入区块链的方法背后的原理在“按需、不可信的熵传递的可扩展架构”白皮书中进行了解释。
解密
尽管decrypt数据源可以像其他数据源一样使用,但它是专门设计用来在嵌套数据源中使用的,以启用部分查询加密。
结果是解密的查询字符串。请注意,加密特性提供的所有逻辑、限制和工具也适用于这里。
嵌套
嵌套数据源是一个元数据源,它不提供对其他服务的访问。它的设计目的是提供一些简单的聚合逻辑,使单个查询能够利用基于任何可用数据源的子查询,并生成单个字符串。
查询格式可以指定一个子数据源和一个子查询,如下所示:
[datasource_name] query_content
请注意分隔数据源名称的方括号和实际子查询的前缀空格。子查询内容可以用单引号或双引号分隔。
通过使用 “${” 特殊的开始符和 “}” 特殊的结束符作为分隔符,您可以选择性地指定多个子查询。
例如:
[WolframAlpha] temperature in ${[IPFS] QmP2ZkdsJG7LTw7jBbizTTgY1ZBeen64PqMgCAWz2koJBL}
集成
公有链
Provable原生集成了最广泛使用的公共区块链协议,如以太坊、比特币、Rootstock、EOS主网和测试网。
可选择的公有链
Provable是不断研究新的公共区块链协议,并考虑进一步的与区块链进行集成。由于Provable引擎完全与区块链无关,并且可以通过HTTP API进行交互,因此鼓励开发人员在以太坊-桥模型上进行独立的Provable开源集成。
基于Ethereum的私有链
私有的、基于以太坊的链目前可以通过使用以太坊-桥与Provable链集成。包括Monax等以太坊分叉。关于如何使用以太坊桥的更多信息,请参阅开发工具部分,或参考StackExchange的回答,该回答描述了如何与testrpc一起使用以太坊桥。
可选择的私有链
“Provable”已经在大多数私有链中使用,如果您对在尚未集成的情况下使用它感兴趣,请与我们联系。
非区块链应用程序
oraclize-lib通过提供一个可以解析为ProvableHTTP API的抽象层,也可以在非区块链环境中使用Provable引擎功能。oraclize-lib目前还处于实验阶段。
Ethereum
下一节专门介绍以太坊和Provable的集成。为了更好地从本节文档中获益,需要事先了解Solidity和以太坊。
Provable和以太坊智能合约之间的交互是异步的。任何数据请求都由两个步骤组成:
1.首先,在最常见的情况下,执行智能合约功能的事务是由用户广播的。该功能包含一个特殊指令,该指令显示给Provable,Provable一直在监视以太坊区块链以获取该指令,这是对数据的请求。
2.其次,根据该请求的参数,可证明将获取或计算结果,构建、签名并传播携带结果的事务。在默认配置中,这样的事务将执行__callback函数,该函数应由其开发人员放置在智能合约中:因此,该事务在文档中被称为Provable的回调事务。
如前几节所述,Provable的基本特性之一是能够将数据返回到智能合约,同时提供数据真实性的一个或多个证明。真实性证明的生成是可选的,它是一个合约范围的设置,在发起数据请求之前,智能合约开发人员必须对其进行配置。可证明总是建议在生产部署中使用真实性证明。
快速启动
这里编写的代码示例的目标是solididity 0.4,并导入provableAPI_0.4.25。sol是一种目标固体度为0.4.25但兼容到0.4.22的release。建议任何新项目通过“github.com/provable-things/ethereum-api/provableAPI.sol”导入最新的API,该API应该针对最新的稳定可靠编译器。
引入以太坊Provable集成的最简单方法是通过展示一个工作示例,如右边的智能合约。该合同使用Provable从Coinbase Pro api获取最后一个ETH/USD。每次调用updatePrice()函数时,都会启动更新过程。这个例子展示了使用Provable的两个重要组成部分:
1.该合约应当是使用Provable合约的子代
2.使用Provable合约定义在Provable api文件中,该文件可以从专用的ProvableGithub存储库中获取。
如果使用Remix在任何以太坊网络上编译和部署它,示例中的代码就是开箱即用的:主网、Ropsten、Kovan和Rinkeby测试网。如果使用的是另一个工具,则有必要用provableAPI_0.4.25的本地导入替换import语句。由于直接从Github导入sol文件可能不被支持。
为了简化开发,Provable对使用默认gas参数完成的第一次数据请求不收取合约费用。连续的请求将要求合约支付Provable费用和支付回调交易所需的ether。两者都自动从合约余额中扣除。如果合约没有足够的资金在他的余额中,请求将失败和Provable不会返回任何数据。
只有第一个查询是免费的。确保合同有足够的ETH余额支付以下查询。契约在 'provable_query' 调用时自动计费,但如果余额不足,则会失败。
简单查询
对数据的请求称为查询。provable_query是一个函数,使用Provable契约继承自父函数,它期望至少有两个参数:
1.数据源如URL,WolframAlpha,IPFS,‘Swarm’和其他列出在这里
2.给定数据源的参数。具有以下的例子:
1. 完整的URL,可能包括使用JSON或XML解析助手,如前面的示例所示
2. 或者WolframAlpha公式
3. 或者IPFS多散列
支持的参数的数量和类型取决于所使用的数据源。此外,还将显示并注释更多的代码示例。数据源以及选择的真实性证明决定了合同必须支付的Provable费用。
计划将来的查询
查询的执行可以安排在未来的日期。函数provable_query接受以秒为单位的当前时间延迟或未来时间戳作为第一个参数作为参数。请注意,为了未来的Provable时间戳是接受必须在60天内当前UTC时间的绝对时间戳的选择的情况下,或在一个相对时间的流逝,流逝秒必须等同于不超过60天。
递归查询
通过在其__callback方法中实现对Provable的新调用,使用Provable的智能合约可以有效地实现自治。这对于实现某些链上引用数据的定期更新(如价格提要)或定期检查某些链下条件非常有用。
这个修改后的版本将每60秒更新ETH/USD汇率,直到合同有足够的资金支付Provable费用。
谨慎使用递归查询。一般来说,建议有目的地发送查询。
查询ID
每次调用函数provable_query时,它都会返回一个唯一的ID,这里称为queryId,它取决于之前的请求数量和智能合约的地址。queryId标识为Provable特定查询,并将其作为回调事务的参数返回到契约。
Provable建议智能合约开发人员验证回调事务发送的queryId是否由对provable_query函数的有效调用生成,如本段附带的示例所示。这确保每个查询响应只被处理一次,并有助于避免误用智能合约逻辑。此外,它在区块链重组期间保护智能合约,如本节专用段落所述。
queryId也可以用于在__callback函数中实现不同的行为,特别是当有多个来自Provable挂起调用时。
自定义gas限制和gas价格
起源于__callback函数Provable事务向包含该事务的块中的miner支付费用,就像任何其他事务一样。矿工费用以以太形式支付,计算方法是将支付交易执行成本的gas数量乘以选定的gas/以太价格。Provable将根据智能合约(用于合约范围的设置)和provable_query函数(用于查询特定的设置)中指定的参数相应地设置这些参数。当查询事务执行时,回调事务的miner费用从合约余额中提取。
如果没有指定设置,Provable将使用默认值200000 gas和20GWei。最后一个值目前处于定价区间的高端,但在全网拥堵时,它有助于更快地确认时间。
Provable回调函数gas的另一个值可以作为参数_gasLimit传递给provable_query函数,如下面的示例所示。
回调事务的gas价格可以通过调用可provable_setCustomGasPrice函数来设置,该函数可以在构造函数(在部署智能合约时执行一次)中设置,也可以在单独的函数中设置。下面是修改后的示例contract,以指定回调事务的自定义gas价格4 Gwei和自定义gas限制。
智能合约开发人员应该正确估计并最小化其__callback方法的成本,因为任何未使用的gas都将返回到Provable,并且不会有退款。
当调用 'provable_setCustomGasPrice' 时,参数类型是uint,表示wei的数量。但是,不需要在参数中放入 'wei' 关键字。
真实性证明
真实性证明是Provable的预言机模型的核心。智能合约可以通过调用usingProvable合约中可用的provable_setProof函数来请求真实性证明及其数据。真实性证明可以直接交付到智能合约,也可以保存、上传并存储在IPFS等其他存储介质上。
当智能合约请求真实性证明时,它必须定义一个不同的回调函数,并带有以下参数:
provable_setProof函数期望的格式如下:
proofType和proofStorage都是在usingProvable中定义的字节常量:
校样可用的参数有:
1.proofType_NONE:所有智能合约的默认值
2.prooftype_tlsnoary:仅在以太坊主网上可用
3.proofType_Android
4.proofType_Native
5.proofType_Ledger
而对于proofStorage:
1.proofStorage_IPFS
例如,provable_setProof(proofType_TLSNotary)将返回完整的TLSNotary证明字节作为回调事务中的证明参数。如果相反地使用了provable_setProof(proofType_TLSNotary | proofStorage_IPFS),那么Provable将只返回base58解码的IPFS多哈希作为证明参数。要获得IPFS多哈希,必须将字节编码为base58。方法provable_setProof可以在构造函数中执行,成为契约范围内的持久设置,也可以在进行特定查询之前直接设置。可以通过调用provable_setProof(proofType_NONE)来禁用真实性证明。智能合约开发者应该意识到,helper方法provable_setProof是一个使用provable的内部函数,因此它必须在部署之前的编译时包含在他们的智能合约中。下面的例子建立在我们前面的例子的基础上:
可验证性
支持的证明可以被验证。可使用的工具包括:校验工具。
最佳实践
预计算查询价格
您必须考虑到您的帐户将被记入您的大多数Provable电话的借方。如果您的合约没有包含足够的ETH,查询将失败。根据您的契约逻辑,您可能希望在下一个查询发送之前检查价格。您可以通过调用provable_getPrice来实现这一点,并检查它是否高于当前的合同余额。如果是这种情况,那么provable_query将会失败,您可能想要优雅地处理它。您还可以向provable_getPrice函数添加一个gaslimit参数:provable_getPrice(string datasource, uint gaslimit)。确保provable_getPrice的自定义gaslimit与provable_query的gaslimit相匹配。
映射查询id
发送的查询的回调函数可能会被多次调用。因此,启动一个管理查询id及其状态的映射可能会很有帮助。当查询的回调函数被调用时,require语句检查当前查询id是否需要处理。在一次成功的迭代之后,id被删除,以防止该特定id的进一步回调。
高级的主题
加密的查询
某些环境,例如公共区块链上的智能合约,可能需要一定程度的隐私来保护数据免受公众审查。开发人员可以使用Provable公钥加密查询的一部分(或全部),从而生成加密的Provable查询。想要部署公共网络区块链应用程序的开发人员可能会对加密查询功能感兴趣。例如,如果应用程序利用了来自已验证API的数据,那么向监视公共链的人公开API密钥将是危险的。
因此Provable提供加密的可能性中包含的参数查询Provable公共密钥:
044992e9473b7d90ca54d2886c7addd14a61109af202f1c95e218b0c99eb060c7134c4ae46345d0383ac996185762f04997d6fd6c393c86e4325c469741e64eca9
只有Provable能够使用其配对的私钥解密请求。
为了加密查询,Provable提供了一个CLI工具,可以在这里找到它。另外,加密任意文本字符串的CLI命令是:
python encrypted_queries_tools.py -e -p 044992e9473b7d90ca54d2886c7addd14a61109af202f1c95e218b0c99eb060c7134c4ae46345d0383ac996185762f04997d6fd6c393c86e4325c469741e64eca9 "YOUR QUERY"
这将使用默认的Provable公钥加密查询。然后,可以将加密的字符串用作Provable查询的参数。
您还可以只加密可provable_query()的一个参数,而将其他参数保留为明文。
POST请求也可以使用加密方法:可以加密URL和POST数据字段,示例如下:
加密数据源(本例中为URL):
python encrypted_queries_tools.py -e -p 044992e94…“URL”
返回:
BEIGVzv6fJcFiYQNZF8ArHnvNMAsAWBz8Zwl0YCsy4K/RJTN8ERHfBWtSfYHt+uegdD1wtXTkP30sTW+3xR3w/un1i3caSO0Rfa+wmIMmNHt4aOS
加密参数(在本例中,我们使用JSON解析助手来检索“状态”):
python encrypted_queries_tools.py -e -p 044992e94…"json (https://api.postcodes.io/postcodes) .status"
返回:
BNKdFtmfmazLLR/bfey4mP8v/R5zCIUK7obcUrF2d6CWUMvKKUorQqYZNu1YfRZsGlp/F96CAQhSGomJC7oJa3PktwoW5J1Oti/y2v4+b5+vN8yLIj1trS7p1l341Jf66AjaxnoFPplwLqE=
加密JSON(第三个参数,POST的数据):
python encrypted_queries_tools.py -e -p 044992e94... '{"postcodes" : ["OX49 5NU", "M32 0JG", "NE30 1DP"]}'
返回:
BF5u1td9ugoacDabyfVzoTxPBxGNtmXuGV7AFcO1GLmXkXIKlBcAcelvaTKIbmaA6lXwZCJCSeWDHJOirHiEl1LtR8lCt+1ISttWuvpJ6sPx3Y/QxTajYzxZfQb6nCGkv+8cczX0PrqKKwOn/Elf9kpQQCXeMglunT09H2B4HfRs7uuI
您还可以通过对另一个数据源(如WolframAlpha、比特币区块链或IPFS)的请求来实现这一点。我们的加密系统还允许用户加密任何受支持的数据源选项。
为了防止其他用户使用您的精确加密查询(“重放攻击”),第一个可证明为给定加密查询的合约查询成为其合法的“所有者”。任何其他使用相同字符串的合约都将收到一个空结果。因此,请记住,在使用加密查询重新部署契约时,始终要生成一个新的加密字符串。
上述安全保障仅在主网有效,测试网无效。欲了解更多信息,请联系info@provable.xyz
为了保护明文查询,采用了椭圆曲线集成加密方案。加密的步骤如下:
1.椭圆曲线Diffie-Hellman Key Exchange(ECDH),以secp256k1为曲线,ANSI X9.63以SHA256为密钥推导函数。该算法用于从可证明的公钥和随机生成的开发人员私钥派生共享秘密。
2.共享密钥由AES-256在Galois计数器模式(GCM)中使用,GCM是一种经过认证的对称密码,用于加密查询字符串。认证标签的长度为16字节,IV被选择为'000000000000'(96位长度)。IV可以设置为零字节数组,因为每个共享密钥都是一次性使用的。每次调用加密函数时,都会重新生成一个新的开发人员私钥。最终的密文是编码点(即开发人员的公钥)、身份验证标记和加密的文本的连接。
计算数据来源
向包传递参数
通过向查询数组添加参数,可以将参数传递给包。它们可以在Docker实例中作为环境参数访问。
目前,API支持多达5个内联参数,包括IPFS散列:
传递超过5个参数
如果你需要传递更多的参数,你需要发送一个手动设置的动态字符串/字节数组,例如:
string[]内存myArgs = new string[](6);
myArgs [0] = " MYIPFSHASH”;
…
myArgs[5] = "最后一个参数";
然后,查询将像这样:
传递加密参数
可以使用嵌套和decrypt元数据源传递加密参数,如右边的示例所示。
随机数据来源
在使用Provable合约中,智能合约应该使用Provable接口,增加了一些与Provable随机数据源相关的具体功能。特别是:
Provable_newrandomdquery:正确执行Provable随机DS查询的助手
1. 可provable_randomDS_setCommitment:在智能合约存储中设置当前请求的承诺
2. provable_randomds_gettsessionpubkeyhash:恢复连接器中出现的会话pub key的hash
provable_randomDS_proofVerify_main:执行回调事务返回的证明的验证
1. provable_randomDS_sessionKeyValidity:验证信任的会话密钥链是有效的,并且它的根是一个分类账根密钥
2. matchBytes32Prefix:验证返回的结果是请求数据有效负载上的会话密钥签名的sha256
为了更好地使用随机数据源,建议阅读以下部分。
random datasource目前仅在以太坊主网和所有以太坊公共测试网(Rinkeby、Kovan、Ropsten-revival)上可用——它还没有与私有区块链/testrpc/remix-ide-vm集成。
两方交互
provable_newrandomdquery可以用于不同类型的交互,但是安全性可以通过向请求添加额外的承诺数据来进一步提高。例如,对于两方交互,可以修改provable_newRandomDSQuery,以包含发送方地址和作为承诺数据发送的值。这使得对随机字节的请求更强烈地承诺给当前一方,他们被认为在合同中有利益关系,使得矿工不可能在潜在的分叉或重组当前链上重放交易。
多方交互
在多党互动的情况下,如投票计划或彩票,承诺数据应该包括所有参与者的地址,以确保交易不能被一个矿工在一个分叉或重组链上重放,而一个参与者没有下注。
ProofShield
ProvableProofShield是Devcon4首次引入的概念,您可以在这里观看我们关于“可扩展的链上验证,用于经过验证的数据提要和链下计算”的演示。
这种防护还在试验阶段,请不要在生产中使用。未来将推出可用于生产的版本。
ProofShield使智能合约能够在链上验证Provable提供的真实性证明,这确保在继续使用数据之前,对接收到的数据的真实性进行验证。
要启用ProofShield,只需通过provable_setProof函数设置即可,如下面的代码所示:
一旦启用了防屏蔽,接收到的证明将不是原始的真实性证明,而是防屏蔽证明:提供了一些功能,使防屏蔽证明可以在链上验证。为了验证它,你需要在__callback方法中调用函数provable_proofshield d_proofverify__returncode (queryId, result, proof)并确保它返回0。
目前,proofShield仅在所有以太坊公共测试网(Rinkeby、Kovan、Ropsten-revival)上可用——它还没有与私有区块链/testrpc/remix-ide-vm集成。
下面是一个代码示例,请注意它的完整版本可以在这里找到:
更多的例子
更完整、更复杂的示例可以在Github专用存储库:https://github.com/provable-things/ethereum-examples中找到。
Rootstock
Rootstock是比特币网络的第一个生产侧链。它的目标是在不损害其去中心化和抵制审查特性的情况下扩展比特币的能力。在Rootstock网络上,参与者可以使用名为智能比特币的令牌与智能合约进行交互。比特币和智能比特币之间的联系是由一个杰出玩家联盟维护的,并得到了合并挖矿的支持。
RSK主网和公共测试网现在已经上线,它们都与Provable服务完全集成。
Rootstock上的智能合约由一个升级的但向后兼容的以太坊虚拟机版本执行。这些都是使用可靠的编程语言编写的,并且完全与以太坊智能合约兼容。
经过验证的Rootstock集成实际上与以太坊完全兼容,因为以太坊智能合约可以在Rootstock上本地编译和执行。有关如何在Solidity智能合约中使用可验证服务的更多技术细节,请参阅本文档的以太坊部分。
EOS
下一节将专门介绍与EOS的可验证集成。在阅读本节之前,您必须熟悉EOS平台的关键概念,如合约、事务、动作和CPU/NET/RAM。所以如果事情变得模糊,EOSIO开发门户网站是你最好的朋友。
EOS平台支持C和C++作为契约编程语言,但是目前Provable集成目前只支持C++。
Provable目前与EOSIO主网、公众 “丛林” 测试网和公众 “麒麟” 测试网集成。
Provable提供两个独立的EOS API:一个与CDT 1.6.1兼容,另一个与CDT 1.4.0兼容。
基本原理
Provable合同和EOS合同之间的交互是异步的。任何数据请求都由两个步骤组成:
1.首先,在最常见的情况下,执行合约的给定操作的事务是由用户广播的。该操作包含一个特殊的指令,该指令指示Provable执行链外任务(比如从Web API获取数据,或者可能更多)。
2.其次,根据请求的参数,Provable将获取或计算结果,构建、签名并传播携带结果的事务。在默认配置中,该事务将执行一个回调操作,该操作应由其开发人员放置在合约中:因此,该事务在文档中被称为Provable回调事务。
如前几节所述,Provable基本特征之一是将数据返回到合约的能力,以及支持数据的一个或多个真实性证明。真实性证明的生成是可选的,必须由EOS合同开发人员在发起数据请求时进行配置。Provable总是建议在生产部署中使用真实性证明。
快速启动
包括ProvableAPI
在开始之前,需要包含eos_api.hpp头文件。这个文件包含了我们将使用Provable所有辅助函数。头文件可以从eos-api github存储库中下载。强烈建议始终使用最新版本。
介绍EOS <-> Provable集成,是通过展示一个工作示例,如右边的EOS合同。该合同使用Provable从CryptoCompare的API获取最后的EOS/USD价格。每次调用execquery()动作时,都会启动更新流程。这个例子展示了使用Provable的两个重要组成部分:
1.合约应包括Provable头文件
2.oraclize_query函数和回调操作处理EOS合约和Provable之间的所有通信
示例中的代码在集成了Provable任何EOS网络上都可以开箱即用。
简单查询
对数据的请求称为查询。oraclize_query是函数,在oraclize/eos_api中实现。hpp头文件,它需要至少两个参数:
a.数据源如URL、WolframAlpha、IPFS、‘Swarm’和这里列出的其他数据源
b.给定数据源的参数。例如:
1. 完整的URL,可能包括使用JSON或XML解析助手,如前面的示例所示
2. 或者WolframAlpha公式
3. 或者IPFS多散列
支持的参数的数量和类型取决于所使用的数据源。此外,还将提供代码示例来展示这一点。数据源以及选择的真实性证明决定了合同必须支付的Provable费用。
计划将来的查询
查询的执行可以安排在未来的日期。函数oraclize_query接受以秒为单位的当前时间(相对时间)或未来日期和时间的unix时间戳(绝对时间)延迟作为参数。请注意,为了未来的Provable时间戳是接受必须在60天内当前UTC时间的绝对时间戳的选择的情况下,或在相对时间的情况下,经过秒必须等同于不超过60天。
递归查询
使用ProvableEOS合约可以通过实现一个循环查询来实现Provable回调操作,从而有效地自治。这对于实现某些链上引用数据的定期更新(如价格提要)或定期检查某些链下条件非常有用。
这个修改后的版本将从WolframAlpha API中得到一个随机数,而不是EOS/USD的价格,它将每10秒重新尝试一次,直到合约收到返回的结果“6”。
谨慎使用递归查询。一般来说,建议有目的地发送查询。
检查查询ID
每次调用oraclize_query函数时,它都会返回一个唯一的ID,这里称为queryId,它保证在给定的网络执行上下文中是唯一的。queryId标识为Provable特定查询,并将其作为回调操作的参数返回到合约。
Provable建议EOS合约开发人员验证回调动作发送的queryId是否由对oraclize_query函数的有效调用生成,如本段所示。这确保每个查询响应只被处理一次,并有助于避免EOS合约逻辑的误用。
查询ID验证流程
使用eos_api.hpp中提供的方法来验证查询ID是一个最佳实践:
1. 首先,必须定义宏CONTRACT_NAME,其中它的值将是要部署的合约的名称。
2. 必须调用函数oraclize_queryId_localEmplace(myQueryId),将oraclize_query()返回的查询ID作为参数传递。这个函数将把queryId表中的查询ID保存为一条记录。只需导入API并定义上述宏,就可以定义该表。
3. 函数oraclize_queryId_match(queryId)将执行回调接收到的queryId与queryId表中可用的查询ID之间的匹配。
为了说明这一点,checkqueryid示例重现了所有这些步骤。
queryId还可以用于将不同的行为实现到回调函数中,特别是当有多个来自Provable挂起调用时。
资源分配
回调操作由可验证控制帐户调用,该帐户将负责为操作执行分配资源。适用下列限制:
1.调用帐户不会使用任何RAM,所以EOS合约开发人员应该注意,当需要RAM的操作在回调函数的上下文中执行时,要定义一个合适的付款人(即:合约本身,_self)。
2.最大CPU占用率为100ms
3.最大净使用量为100kb
当需要额外的资源时,EOS开发者可以联系Provable来讨论不同的安排,或者他们可以使用EOS特性来推迟与不同的付款人执行需要资源的任务。
上述限制是实验性的,在EOS主网上发布之前可能会改变。如果被滥用,一些账户可能会被暂时禁止使用该Provable服务。
真实性证明
真实性证明是Provable的预言机模型的核心。EOS合同可以通过在oraclize_query函数的最后一个参数中指定它们想要的证明来请求真实性证明以及它们的数据。真伪可以直接交付到EOS合同中,也可以上传存储在IPFS上。
当一个EOS合同请求一个真实性证明时,它将在回调动作被调用时接收到证明,形式为std::vector<uint8_t> proof 论点。
oraclize_query的证明参数被设计成如下方式使用:oraclize_query(..., (proofType_ | proofStorage_))
proofType和proofStorage都是在预言机中定义的oraclize/eos_api.hpp头文件。
校样可用的参数有:
1.proofType_NONE:任何智能合约的默认值
2.prooftype_tlsnoprivate:仅在EOS主网上可用
3.proofType_Android
4.proofType_Native
5.proofType_Ledger:仅在随机数据源中可用
而对于proofStorage:
1.proofStorage_IPFS
例如,oraclize_query(…, (prooftype_tlsnoary)将返回完整的TLSNotary证明字节作为回调操作中的证明参数。如果oraclize_query(…, (proofType_TLSNotary | proofStorage_IPFS),则Provable将只返回base58编码的IPFS多哈希作为证明参数。强烈建议始终使用真实性证明,但是可以通过将proof参数设置为proofType_NONE或简单地忽略它来禁用真实性证明。
可验证性
支持的证明可以被验证。可使用的工具包括:校验工具。
高级的主题
检查合同查询/cbs
可以监视给定EOS合约之间的交互,并通过使用cleos get动作进行验证。这将显示调用契约和Provable连接器契约之间操作的高级视图。如果您想要看到更多的细节,使用——console选项(或-j)就足够了:这将包括从查询和回调操作生成的任何控制台输出。
test_query页面是另一个有用的工具,用于监视Provable查询的处理(使用oraclize_query返回的queryId作为输入)。
委派资源分配
当使用oraclize_query函数时,将启动对Provable连接器契约的EOS操作。默认情况下,此操作的权限由EOS合同账户本身授予。这可以更改,例如,让契约的用户支付操作资源和Provable服务费(如果有的话):在包含oraclize/eos_api之前定义一个宏ORACLIZE_PAYER就足够了。高压泵头文件。
计算数据来源
向包传递参数
通过向查询数组添加参数,可以将参数传递给包。它们可以在Docker实例中作为环境参数访问。
目前,API支持5个内联参数,包括IPFS散列:
std::vector<std::vector<unsigned char>> myquery = { string_to_vector("QmZRjkL4U72XFXTY8MVcchpZciHAwnTem51AApSj6Z2byR"), string_to_vector("_firstOperand"), string_to_vector("_secondOperand"), string_to_vector("_thirdOperand"), string_to_vector("_fourthOperand") };
oraclize_query("computation", myquery);
传递超过5个参数
如果你需要传递更多的参数,你需要发送一个手动设置的动态字符串/字节数组,例如:
std::string myArgs[6] = { "MYIPFSHASH", ... };
然后,查询就会像这样:
oraclize_query("computation", myArgs);
随机数据来源
包含在可验证的eos_api中。EOS合同应该使用hpp与Provable接口,增加了一些与Provable随机数据源相关的特定功能。特别是:
1.正确执行Provable随机DS查询的助手
2.oraclize_randomDS_proofVerify:执行回调事务返回的证明的验证
指定网络环境
强烈建议开发人员定义网络上下文和将在其中运行智能合约的合约名称。
对于网络环境:
1.对于EOS测试网丛林:#define ORACLIZE_NETWORK_NAME "eosio_testnet_jungle"
2.用于EOS主网:#define ORACLIZE_NETWORK_NAME "eosio_mainnet"
合同名称:
1.#define CONTRACT_NAME "contractname"
定价
与EOS的可验证集成目前可在EOSIO主网和EOSIO公共“丛林”测试网上获得;
Provable目前是免费的。
我们的标准定价表可能最终适用(收取的EOS代币等值美元价值),稍后在EOSIO主网上。如果发生这种情况,同样的定价逻辑将在测试网上发生,以模拟功能。这将在testnet EOS中收费,所以是免费的。合同已经被部署在免费期内将遗产,我们将继续提供服务,因为这是对他们来说,然而,他们featureset也会留在遗留光谱(即新特性依赖于定价模型显然是不会的可转移到这些)。
C• Corda
这里我们将讨论Provable Corda积分。在阅读本节之前,您必须熟悉Corda平台的关键概念,如流、子流、合约、事务、命令、预言机等。因此,如果事情变得模糊,Corda文档是你最好的朋友。
快速启动
Provable的服务非常类似于Corda中描述的预言机模型,但是它没有提供对query()和sign()方法的直接访问,而是实现了一组流,当需要来自外部的数据时可以调用这些流。看看下面的步骤,看看如何实现这一点。
查询Provable
查询Provable最快方法是使用OraclizeQueryAwaitFlow,它接受前面几节中定义的参数(有关更多细节,请参阅Provable引擎)。如右边的代码所示,流从指定的api获取美元/英镑的汇率,需要TLSNotary类型的证明。请注意,json(…)解析器将准确地提取我们所关心的结果。
由于流之间的通信是阻塞的,当前的流将保持空闲,直到Provable将处理回答案。
一旦成功返回答案,就可以通过使用OraclizeUtils中定义的ProofVerificationTool轻松地验证证明。
为了安全检查收到的数据的真实性,习惯上要验证包含在Provable答案中的证明。一旦verifyProof方法成功(返回'true'),用户就可以确定结果既没有被证明也没有被其他方面篡改。这可以从加载了CorDapp的交易所涉及的各方进行检查。请注意,ProofVerificationTool是一个包含在Provable的CorDapp中的模块,它在节点内本地执行验证。
如果希望将结果放入事务中,则有必要将答案与Provable节点公钥一起包装在命令中。请注意,Provable节点可以通过使用serviceHub获得。identityService,用OraclizeUtils.getNodeName()标识节点。
建立事务
现在我们有了建立事务的所有要素:检查右边的代码,看看它是如何完成的。
注意:
1.someNotary是您选择的一个公证员节点,例如:
val someNotary = serviceHub.networkMapCache.notaryIdentities.first()
2.someState是一种输出状态,通常与预言机的答案一起存在。
3.someContract是一个有效的Corda合约,它列出了I/O状态上的所有断言,通过requireThat闭包(参见下面关于该合约的更多细节)。
4.someCommand是一个指定事务(包括颁发者公钥)正在执行的操作的命令。
签署事务
在将事务发送给Provable进行签名之前,习惯上要过滤掉所有不Provable数据,如右边的函数过滤所示。
然后可以使用OraclizeSignFlow请求签名,它接受前面as参数定义的FilteredTransaction。该流将检查查询是否在过去实际提交过,然后返回一个包含Provable签名的事务签名。
细节
Provable答案
由Provable答案模型定义允许访问以下信息:
1.queryId:当前答案的查询ID
2.rawValue:实际的结果(可以是一个字节数组或字符串)
3.value:结果的字符串表示形式(如果是ByteArray,则为十六进制字符串)
4.proof:作为字节数组的证明
5.type:指定rawValue字段类型的字符串
5.1. 如果是字符串则为"str"
5.2. 如果它是一个字节数组,则使用"hex"
合约
由于答案通过命令的方式包装在一个事务中,您可以通过使用tx.commands.requireSingleCommand<Answer>()在一个合约中轻松地访问它,并检查答案是否满足所有的要求。
在右边,我们验证存储在答案中的值是高于某个阈值的常数,同时验证所请求的证明。如果上述断言之一失败,则拒绝合约并停止流。
RPC调用
也可以通过RPC使用崩溃shell(>>>)调用OraclizeQueryAwaitFlow,如图所示。
例子
在CorDapp中,你可以找到一个现成的例子,如果美元/英镑的汇率高于某个阈值,它就会自己发行指定数额的现金。查看corda-api存储库,了解它如何工作的全部细节。
然后,您可以通过查询如图所示的保险库来检查交易。
将CorDapp添加到项目中
如果你想在你的项目中使用Provable的CorDapp,只需要在你的build.gradle文件中放入一个依赖项:
1.编译 "com.github.oraclize:corda-api:linux_x86_64-SNAPSHOT"
2.编译 "com.github.oraclize:corda-api:win32_x86_64-SNAPSHOT"
3.编译 "com.github.oraclize:corda-api:macosx_x86_64-SNAPSHOT"
要使证明验证工具正确工作,有必要将正确的依赖项与节点的架构相对应,否则证明将失败,引发如下所示的异常。
# Fabric
下一节将专门介绍与Hyperledger Fabric的Provable集成。
Hyperledger Fabric平台支持Go、Node和Java作为链代码的主要编程语言;然而,当前Provable集成(虽然它在内部使用一个节点chaincode)的形式提供了一个API,可以通过一个包——这意味着您将能够使用从你的轻松去chaincodeProvable,但在未来的Node / Java可以很容易地支持。
为了更好地利用本节文档,需要具备Go、Node、Docker和Hyperledger Fabric的之前知识。
如前几节所述,Provable基本特征之一是将数据返回到合约、Fabric空间中的链代码以及支持数据的一个或多个真实性证明的能力。真实性证明的生成是可选的,必须由chaincode开发人员在发起数据请求时进行配置。Provable总是建议在生产部署中使用真实性证明。
快速启动
介绍与Hyperledger Fabric的Provable集成的最简单方法是通过展示一个工作示例。
这个例子使用Provable从cryptocompare.com api获取最后的欧元/美元汇率。每次发送查询时都会启动更新流程。这个例子展示了使用Provable时需要的两个重要组件,它们都可以从Github上专用的fabric-apiProvable存储库中获取:
1.Provable连接器链代码connector/oraclize-connector.js,需要安装在网络对等体上;
2.Go包 - oraclizeapi.go - 需要从用户定义的go链代码中使用ProvableAPI。
Provable目前可以在任何Hyperledger Fabric网络中免费使用。这将在不久的将来改变,标准定价将适用:更多细节请查看文档的定价部分。付款将在Fabric网络之外采取专用用户帐户持有一些预付信贷。
先决条件
文档中描述的Provable集成假设用户至少熟悉Hyperledger Fabric文档提供的第一批教程中的一个。本教程可以在以下链接中找到:编写第一个应用程序。
体系结构概述
为了让用户接近Hyperledger Fabric区块链,通过官方的Hyperledger来源提供了几个示例。包含这些示例的文件夹中包含了一些基本的网络配置,这对于具有清晰而简单、Provable集成非常有用。包含示例的fabric-samples文件夹可以通过执行以下命令下载:
curl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.0
该命令下载fabric-samples文件夹;具体来说,文件夹fabric-samples/basic-network是我们将要用来展示Provable集成的网络。基础网络创建了一个由以下实体组成的网络结构:
1.一个应用程序(cli);
2.一个对等;
3.一个开证申请人;
4.一个CA。
在对等端将安装两个链码:
1.oraclize-connector,由Provable提供的chaincode,被Provable内部使用来执行任何查询;
2.user-chaincode,用户想要创建的链代码,以便在Hyperledger Fabric区块链中构建一个服务。
关于这个Fabric网络例子中的生态实体的图例如下图所示:
网络结构如下图所示:
交易流
在本节中,我们将分析在集成Provable基本网络示例中执行的查询的事务流。交易流程的第3个步骤如下图所示:
流程可分为以下过程阶段:
1. 在应用程序A中,用户启动指向对等体P1的查询,调用Go用户链码S1的函数,该函数调用一个Provable查询;
2. 用户链码S1,执行用户调用的函数,并将Provable查询的数据发送给Provable连接器,链码S2;
3. Provable链码S2,一旦结果就绪,将其连同真实性证明一起发送回用户链码S1;
4. 用户链码S1使用从Provable程序收到的结果(和真实性证明)做一些事情,并最终将响应发送回应用程序A。
构建网络
本小节的目标是构建如图所示的网络。首先,访问fabric-samples文件夹并为我们的Provable集成示例创建一个项目文件夹。在本文档中,它的名称是fabric-samples/oraclize-integration。这个文件夹是应用程序-cli端发生的所有操作的容器。在oraclize-integration文件夹中,我们会有以下文件:
1.enrollAdmin.js
2.registerUser.js
3.startFabric.sh
4.user-application-query.js
两个文件enrollAdmin.js和registerUser.js都可以从fabric-samples/fabcar文件夹中复制。可以从fabric-samples文件夹中启动以下命令:
1.cp fabcar/enrollAdmin.js oraclize-integration
2.cp fabcar/registerUser.js oraclize-integration
然后,在oraclize-integration文件夹中安装以下软件包:
1.npm install fabric-client
2.npm install fabric-ca-client
从Github上的fabric-examples Provable repository中下载名为fabric-examples/eurusd-example/testing-utils/startFabric.sh的文件。这个脚本在右边的代码部分中显示,它是用来执行以下操作的脚本:
1. 设置环境变量;
2. 清理证书和密钥库,删除hfc-key-store文件夹;
3. 停止并移除所有先前的代表网络实体的docker容器;
4. 移除chaincode容器;
5. 启动network fabric-samples/basic-network,创建一个docker容器:
5.1.开证申请人;
5.2.CA;
5.3.对等;
5.4.cli;
5.5.couchdb;
6. 启动命令行来安装和实例化oraclize-connector和user-chaincode chaincodes,将它们作为容器启动;
7. 安装节点模块;
8. 注册管理调用enrollAdmin.js;
9. 注册用户,调用registerUser.js。
请注意必须安装Go,并且必须正确设置Go环境变量。
添加Provable链代码
在startFabric.sh脚本中,最后两个docker命令引用实例并安装可验证的连接器链代码。这个链代码,在文档中以oraclize-connector的名字引用,从cli docker容器在网络对等体上实例化。
cli容器从其本地的chaincode集实例化和安装预言机的chaincode。然而,cli从fabric-samples/chaincode文件夹获取这个chaincode集;因此,node.js oraclize-connector和Go用户链代码必须在上述路径中。
的oraclize-connector.js chaincode提供Provable在fabric-api/connector Provable repository on Github,并将在以下路径fabric-samples/chaincode/oraclize-connector/node,因此,最终结果将会是:fabric-samples/chaincode/oraclize-connector/node/oraclize-connector.js。
为了正确设置oraclize-connector链代码,需要安装oraclize-connector.js文件和package.json是必要的。安装指定的依赖项需要package.json,而oraclize-connector.js本身是节点Provable链代码。
请注意,所提到的路径和名称没有为正确的集成而更改。
添加用户链代码
创建一个包含你的链代码 fabric-samples/chaincode的文件夹,在这个例子中fabric-samples/chaincode/user-chaincode/go。创建Go chaincode,在本例中引用的名称是user-chaincode.go。现在,为了执行Provable查询,必须包含Provable Go包。在Github上的fabric-examples/eurusd-example/chaincode/go/ Provable 存储库中,我们提供了一个现成的用户链代码。在chaincode中,包含了所有需要的依赖,包括oraclizeapi.go。但是,你需要在本地安装依赖,使用以下命令:
go get "github.com/oraclize/fabric-api"
请注意所有的go包,包括oraclizeapi.go,必须是你的chaincode文件夹fabric-samples/chaincode/user-chaincode/go的供应商。一般来说,通过govendor提供包是一个很好的解决方案,可以在用户链代码中包含包。这个包必须出现在fabric-samples/chaincode/user-chaincode/go/vendor目录下。
这个包允许使用一个Provable查询函数来执行数据请求,代码如下:
oraclizeapi.OraclizeQuery_sync(APIstub, dataset, url, proofType)
在用户链代码中,一个函数执行欧元/美元汇率数据调用,使用可证明的查询显示在右边。本例中链代码要求的证明是TLSNOTARY证明。
Provable简单查询
对数据的请求称为查询。OraclizeQuery_sync是一个函数,在oraclizeapi中实现oraclizeapi.go Go包,它需要三个参数:
1. 这里列出的数据源如URL、WolframAlpha、IPFS、Swarm等
2. 给定数据源的参数;例子:
2.1. 完整的URL,可能包括使用JSON或XML解析助手,如前面的示例所示
2.2. 或者WolframAlpha公式
2.3. 或者IPFS多散列
3. 从oraclizeapi.go导入的证明类型,可以使用以下值指定:
3.1. NONE
3.2. TLSNOTARY
3.3. ANDROID
3.4. LEDGER
3.5. NATIVE
支持的参数的数量和类型取决于所使用的数据源。
发送CLI查询
为了测试fetchEURUSDviaOraclize这个从用户链代码中调用Provable查询的示例函数,你需要先启动网络。启动Docker守护进程后,在fabric-samples/oraclize-integration文件夹中运行以下命令:
./startFabric.sh
然后,当网络完全打开时,使用所有7个容器(4个实体、2个链代码、1个couchdb),运行应用程序查询文件user-application-query.js,使用命令:
node user-application-query.js
欧元/美元的汇率结果返回与真实性证明指定的链码方。
关于上面示例文件的完整代码,请参考Github上的fabric-examples可证明存储库。
开发工具
在本节中,开发人员将发现一些工具,这些工具可以帮助他们将可证明的集成到他们的产品中。
测试查询
TestQuery页面可用于测试任何可证明的查询。这不需要编写任何代码,对于在早期开发阶段验证给定查询的正确性非常有用。
网络监控
网络监控,连同证明验证工具,可以用来验证已提供的真实性证明的完整性和正确性。
独立地验证这些证明是否有效是非常重要的,因为这是唯一的方法来验证,如果可证明的答案是错误的。
加密
为了使用可证明的加密支持特性,开发人员可以使用TestQuery页面或Python加密工具。为了避免重放攻击,加密查询被链接到第一个智能合约,该智能合约使用它来执行一个请求以进行验证。需要重新部署相同的智能合约代码来加密查询。
Remix IDE Provable插件
Remix IDE与各种插件捆绑在一起,包括一个用于将Provable作为预言机服务使用的插件。这个插件是为JavaScript VM使用的,它在加载时为您的会话部署所有需要的基础设施和侦听器。此后,您可以利用useingOraclize合约的继承性来部署任何合约,并通过IDE侧面板上的插件图标来跟踪任何查询请求。
关于一些合同的示例,请参考ethereum-examples github存储库。根目录中的合约,如DieselPrice。索尔和KrakenPriceTicker。sol是即插即用的,因为您可以简单地在Remix中与插件一起运行它们,它们将会工作。
插件仅适用于JavaScript VM环境对混音,对于使用web3提供者或注入环境,网络问题要么需要支持的直接可证明的,这是对公共testnets或mainnet,或在私有网络的情况下,通过“ethereum-bridge”将需要手工设置。
单元测试
在移动到正式测试网或生产使用之前,智能合约开发的一个重要步骤是单元测试。以太坊社区已经开发了多个单元测试框架,如Truffle和Embark,它们可以在以太坊的私有实例上测试合约。一种常见的组合是在以太坊js-testrpc环境中运行Truffle测试,该环境是在内存中运行的一个模拟以太坊区块链实例。为了能够与Truffle部署的智能合约进行交互,或者启动test-rpc区块链实例,需要安装一个称为以太坊-桥的工具。这是一个nodejs模块,它在实例中部署可验证的智能合约基础设施,然后监控该基础设施以查看请求。该工具将请求转换为可验证引擎的HTTP API调用,然后通过广播回调事务返回结果。
EthPM
以太坊包管理是一个旨在标准化、构建和维护基于智能合约包的公共注册表的项目,以帮助智能合约开发者。可证明已经在“oracle -api”包下发布并维护了以太坊的oraclizeAPI。安装程序:“truffle install oracle -api”。
请注意正确的包名是' oraclize-api ',而不是 ' oraclize '。
Oraclize-lib
Oracle-lib是一个实验性的nodejs库,用于利用可证明来构建非区块链应用程序。可以将其视为Provable HTTP API的一个简单抽象层。
未来
Stargate
Provable团队正在开发一种工具,可以直接集成基于以太坊的链的任何私有部署,包括私有测试网,而无需安装额外的软件。这个工具被命名为“Stargate”,目前正在积极开发中。该工具将由开发人员区块链实例和可证明的ssh-bridge组成。更多的信息将在今年晚些时候公布。有兴趣尝试这个实验性功能的各方,可以联系我们。
安全性深入研究
随着数字技术降低了信息创建和发布的门槛,能够验证一条信息是否来自已知的、可信的来源就变得极其重要。
在web技术的上下文中,身份验证是由HTTPS协议提供的,它是HTTP协议的扩展,在客户端和包含数据的web服务器之间创建一个加密和身份验证的通道。
在处理可用于确定不同金融交易的数据时,身份验证就变得至关重要。不幸的是,最常用和可用的区块链协议没有直接与HTTPS交互的方法,因此无法消化经过身份验证的数据。这样看来,似乎需要一个可信的服务,它可以提供数据或基于数据完成操作;但这在一定程度上削弱了在没有可信方参与的情况下使用去中心化协议交换价值的意义。
这就是为什么Provable一直在设计数据身份验证系统,并将其作为其核心业务的一部分。这些系统被称为真实性证明,它可以在交付未被篡改的数据时审计预言机的服务记录。真实性证明利用不同的认证技术:一些基于软件,一些依赖可信的硬件技术。
真实性证明类型
TLSNotary证明
TLSNotary证明利用了TLS 1.0和1.1协议的一个特性,该特性允许在三方之间拆分TLS主密钥:服务器、被审计方和审计方。在这种方案中,Provable是被审核方,而特定设计的开源Amazon机器映像的一个锁定的AWS实例充当审核方。TLSNotary协议是一种开源技术,由PageSigner项目开发和使用。
Android证明
Android Proof是一些可证明的内部研发工作的结果。它利用了谷歌开发的名为SafetyNet的软件远程认证技术,来验证给定的Android应用程序是否运行在一个安全的、没有被Root的物理设备上,并连接到Provable的基础设施。它还远程验证应用程序代码哈希值,启用在设备上运行的应用程序的身份验证。应用程序代码是开源的,因此可以对代码哈希值进行审计和验证。Android证明更进一步,通过使用新引入的Android硬件验证来证明物理设备已更新到最新可用的Android版本,通过对系统内的任何潜在漏洞进行修补,进一步确保完整性。此外,它还验证设备的Root-of-Binding-Trust是否有效。这两种技术一起有效地将物理Android设备转变为一个可证明安全的环境,在这个环境中可以启动到远程数据源的未篡改的HTTPS连接。与未经授权的可证明的或外部攻击者获得妥协的基础设施设备,生成一个错误但有效的证据,一个零日漏洞不知道谷歌必须由党说,发现这打破了Android沙盒模型或者是一个内核级利用,可用的最新版本的Android操作系统及其安全补丁。您可以通过阅读关于Android证明的白皮书来获取更多信息,并在以太坊和比特币测试网上进行试验。基于谷歌的更新,正在主网上启用Android Proof,有效启用了Android Nougat 硬件认证。
账本凭证
Ledger是一家法国公司,在生产硬件强制加密货币钱包方面处于领先地位。他们的主要产品是Nano和Blue账本。这两个设备都实现了一个公共平台,包括意法半导体安全元件、控制器和一个名为BOLOS的操作系统。BOLOS SDK允许开发人员构建应用程序,这些应用程序可以与加密货币钱包一起安装在安全硬件上,这些应用程序本身就是BOLOS应用程序。BOLOS公开了一组内核级API,这些API可以完成一些有用的操作,比如加密操作或认证操作。事实上,认证是该平台最有趣的方面之一:任何应用程序都可以通过调用适当的API,要求内核度量其二进制数据并生成签名哈希。签名由一个特殊的验证密钥执行,该密钥由内核控制,应用程序开发人员无法实现。认证密钥具有完整的信任链,该信任链的根在由账本控制的主密钥中,驻留在由账本控制的HSM上。
账本证明利用代码证明和设备证明功能,向任何第三方证明由可证明开发的应用程序正在一个真正的账本设备的TEE中运行。账本凭证有以下格式:
1.表示证明类型和版本控制的前缀
2.设备的验证密钥app_key_1。
3.在app_key_1上使用账本根键进行签名
4.应用的资料及签名
账本证明目前被Provable随机数据源用于为智能合约、区块链和非区块链上的应用程序提供未经篡改的熵。
贮存和运输
真实性证明可以是相当大的文件,最多可达几千字节。直接在以太坊交易的数据负载结果中交付这种证明可能成本会非常昂贵,就EVM执行成本而言,甚至对于更大的数据可能是不可能的。
此外,Provable努力成为区块链不可知者,使证明甚至可以在比特币和其他区块链上使用。因此,证明被上传并保存到分布式存储系统IPFS中。在提供指向内容的指针时,IPFS使用一种称为multihash的自定义哈希算法。生成的地址是Base64编码的,它是特定于文件的唯一ID,可以使用该ID对文件进行全局访问,并随对所包含的文件的任何编辑而更改。
IPFS本身并不提供任何长期的持久性保证,但是作为可证明基础设施的一部分,它运行IPFS持久性联盟。任何人都可以加入可证明的联盟,并通过将IPFS持久性联盟节点指向以下聚合对等体来帮助保存所有证明的独立副本:
QmSsSSfJAJwj3jsNfzbSrxtLAjhpYPjbUEsCQT8mWVgBiL
先进的数据来源
随机数据来源
Provable的随机数据源利用账本证明和自定义应用程序来生成无偏随机数,并按需向区块链和非区块链应用程序提供它们。最终应用程序可以执行验证步骤,以确定所提供的随机性是否真的在Ledger Nano提供的安全硬件环境中生成。
本节将简要解释自定义应用程序的基本原理和内部工作原理。
设计的主要目标是:
1.Provable只能请求一次,对于一个特定的请求,给设备一个随机数。后续请求将被拒绝或返回先前提取的号码。
2.必须对随机数进行签名,以验证设备生成的随机数。
3.在区块链应用程序中,矿工不应该能够篡改订单、有效性和投注结果
4.设计应尽量减少在设备和链上使用状态。
该体系结构通过以下方式实现这些目标:
1.强制每个请求id的唯一性。设备保持一个merkelized, append-only的状态,其中看到的每个请求都被追加。
2.来自设备的所有数据都由应用程序会话密钥签名,其公钥存在于Provable的连接器中。请求可以通过一个精确的会话密钥提交以接收结果。
3.承诺数据与请求一起发送,以将其锚定到特定的区块链历史记录。承诺数据可以通过当前块信息(如时间戳、coinbase和以前的块散列)以及与请求相关的额外信息((msg.sender,msg.value等)。
4.内核有一个事件特性,它被用来增加应用程序内部计时器。请求可以并且应该指定一个时间(以秒为单位),该时间必须在设备提供请求和返回的随机数之前经过。说明符时间越长,针对矿工(无论是否有可证明的协作)篡改结果的安全性就越强。
5.使用ECDSA确定性签名从承诺数据和会话私钥生成随机字节;这避免了为标记已服务的查询而重新计算树的代价。
这些操作的有效性由账本证明来强制执行。与随机数据源相关的签名和数据实际上附加到账本证明中,并与结果一起返回。追加的数据格式如下:
1.应用程序二进制文件的SHA-256,由BOLOS内核测
2.uniqueId散列
3.应答请求之前所经过的时间
4.必须返回的随机字节数
5.由开发人员选择的承诺数据
6.应用程序会话的签名在请求数据上生效
7.应用程序会话公钥
8.验证密钥app_key_1的签名通过代码哈希和会话公钥
对随机数据源的深入解释和对攻击场景的分析可以参考已发布的论文。
定价
使用Provable需要支付少量费用,这取决于所使用的数据源类型和所要求的真实性证明。下面列出的价格对以太坊和Rootstock都有效。查询本身有一个基本价格。当oraclize_query被调用时,需要的ETH必须被转移到Provable,以支付将回调事务发送回合约的费用。
因为这个成本取决于代码和首选项(gasprice),它可以根据两者的不同而变化很大。为了避免不必要的成本,您应该尽可能精确地估计和设置gas的价格和gas,以便您获得合理的确认时间,并使您的回调事务按照预期工作(而不会耗尽gas)。
第一次自由请求
为了方便测试,如果使用标准设置,从任何智能合约地址对可证明的第一次调用都是免费的。这包括回调事务的gas成本。
Testnets政策
为了保持与部署的主网的兼容性,在任何测试网上验证的智能合约都需要支付与主网相同的费用。由于预期的支付是在testnet Ether中,它没有价值,对可证明的调用实际上是免费的。经证实,保留权利停止滥用或过度使用服务。
调用费用
oraclize_query在执行时自动恢复费用。费用由两部分组成:
1.数据来源的美元价格和要求的真实性证明所对应的Wei金额,使用最近的汇率
2.Provable将在gas中花费的Wei数量用于发送回调事务
在线支付和离线支付
当在链上支付时,没有可靠的向后兼容的方式来证明归还gas“变化”。这是由于以太坊的工作方式:在交易得到确认之前,不可能确定将使用的确切gas数量,因为它取决于当前状态。之后将未用完的gas送回可能会产生副作用。
可证明现在也支持链下支付。当使用该选项时,你将得到未使用的gas,因为费用发生在区块链以外的预付帐户。感兴趣的人士请通过info@oraclize.it联系
嵌套查询
目前,嵌套查询被定价为单个查询。在不久的将来,嵌套查询的定价将是您决定使用的数据源的总和。目前,价格降至单个数据源,然而,您的智能合约应该考虑到,在某些时候将适用完整的价格。
教程
在Provable的Youtube频道,你可以找到一些有用的视频开始使用Provable的集成。