频道栏目
首页 > 系统 > Linux > 正文

世界杯外围投注官网

2018-11-27 09:53:52           
收藏   我要投稿

如何将JSON文件存储在IPFS上,并使用Oraclize访问智能合约中的数据呢?

以太坊是一个成熟的区块链,使开发人员能够创建智能合约,在区块链上执行的程序可以由交易触发。人们经常将区块链称为数据库,但使用区块链作为数据存储非常昂贵。

以目前的价格(530美元,4gwei)在以太坊上存储250GB将花费你106,000,000美元。一般来说,我们可以忍受高成本因为我们:

不会在以太坊区块链上保存那么多数据。

区块链的审查制度,透明度和稳健性是值得的。

如果你是以太坊的新手,请查看此介绍。

去中心化存储

IPFS(星际文件系统)对区块链存储有一些保证,即去中心化和防篡改,但不比传统的磁盘空间花费更多费用。使用EBS 250GB存储运行EC2 t2.micro实例将花费你大约15美元/月。IPFS的一个独特功能是它处理文件的方式。它不使用基于位置的寻址(如域名,IP地址,文件路径等),而是使用基于内容的寻址。将文件(或目录)添加到IPFS存储库后,可以通过其加密哈希来引用它。

$ipfsaddarticle.json
addedQmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYMarticle.json
$ipfscatQmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
{"title":"Thisisanawesometitle","content":"paragraph1\r\n\r\nparagraph2"}
$curlhttps://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM{"title":"Thisisanawesometitle","content":"paragraph1\r\n\r\nparagraph2"}

然后,你可以使用IPFS客户端或任何公共网关访问文件。你还可以创建非公共网关,默认情况下使其成为可写(只读),并实现授权方案,以便以编程方式访问IPFS网络。

重要的是要了解IPFS不是一种服务,其他节点将存储你的内容。如果你的内容不受欢迎,如果他们没有固定哈希(他们不想租用磁盘空间),垃圾收集器会将其从其他节点中删除。只要网络上至少有一个对等体确实关心你的文件并且有兴趣存储它们,网络上的其他节点就可以轻松获取该文件。即使你的文件从网络中消失,也可以在以后再次添加,除非其内容发生更改,否则其地址(哈希)将相同。

IPFS和以太坊智能合约

尽管以太坊协议没有提供任何连接到IPFS的本地方式,但我们可以回到像Oraclize这样的离线解决方案来解决这个问题。Oraclize允许使用各种数据提供智能合约。其中一个可用的数据源是URL。我们可以使用公共网关从IPFS上的JSON文件中读取。依靠单个网关会很单薄。我们将要使用的另一个数据源是IPFS。通过使用JSON解析器(它是查询的一部分)读取Oraclize智能合约,我们可以在JSON文档中提取特定字段。

oraclize_query("IPFS","json(Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM).title"));

如果Oraclize可以在20秒内获取文件,则可以预期获得异步请求。如果使用连接良好的节点上传文件,则不需要关注超时。我们的EC2(欧盟法兰克福)实例连接到大约750个同行。通过公共网关或本地运行守护进程获取文件几乎是即时的。响应是异步的,oraclize_query调用返回查询id(bytes32)。你可以将其作为来自Oraclize的数据的标识符。

function__callback(bytes32_queryId,string_data)public{require(msg.sender==oraclize_cbAddress());
process_data(_data);
}

出于安全原因,我们希望确保只允许Oraclize调用__callback函数。

你可以在GitHub上找到博客示例的完整世界杯外围投注网站库:tooploox/ipfs-eth-database

性能和实施

最初,我很担心性能表现。它是否可以像集中服务发送响应一样快速地获取IPFS上托管的JSON文件?结果令我很惊喜。

$wrk-d10shttps://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
[email protected]://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
2threadsand10connections
ThreadStatsAvgStdevMax+/-Stdev
Latency59.18ms24.36ms307.93ms94.73%
Req/Sec86.3415.48101.0085.57%
1695requestsin10.05s,1.38MBreadRequests/sec:168.72
Transfer/sec:140.70KB

在我们审查博客时,作者必须在智能合约上调用addPost时仅输入IPFS哈希值。我们使用IPFS和Oraclize从文件中读取标题,以使用以太坊事件存储它。我们不需要为其他智能合约保留标题,因此使用事件对于我们的用例来说已经足够了。这可能不是最具开创性的例子,但很好地展示了如何优化低交易费用。

pragmasolidity0.4.24;
import"openzeppelin-solidity/contracts/ownership/Ownable.sol";
import"./lib/usingOraclize.sol";
import"./lib/strings.sol";

contractBlogisusingOraclize,Ownable{usingstringsfor*;
mapping(address=>string[])publichashesByAuthor;
mapping(bytes32=>string)publichashByQueryId;
mapping(bytes32=>address)publicauthorByHash;eventPostAdded(addressindexedauthor,stringhash,uinttimestamp,stringtitle);eventPostSubmitted(addressindexedauthor,stringhash,bytes32queryId);uintprivategasLimit;
constructor(uint_gasPrice,uint_gasLimit)public{
setCustomOraclizeGasPrice(_gasPrice);
setCustomOraclizeGasLimit(_gasLimit);
}functiongetPrice(string_source)publicviewreturns(uint){returnoraclize_getPrice(_source);
}functionsetCustomOraclizeGasPrice(uint_gasPrice)publiconlyOwner{
oraclize_setCustomGasPrice(_gasPrice);
}functionsetCustomOraclizeGasLimit(uint_gasLimit)publiconlyOwner{
gasLimit=_gasLimit;
}functionwithdraw()publiconlyOwner{
owner.transfer(address(this).balance);
}
function__callback(bytes32_queryId,string_title)public{
require(msg.sender==oraclize_cbAddress());
require(bytes(hashByQueryId[_queryId]).length!=0);stringmemoryhash=hashByQueryId[_queryId];
addressauthor=authorByHash[keccak256(bytes(hash))];
hashesByAuthor[author].push(hash);emitPostAdded(author,hash,now,_title);
}functionaddPost(string_hash)publicpayablereturns(bool){
require(authorByHash[keccak256(bytes(_hash))]==address(0),"Thispostalreadyexists");
require(msg.value>=oraclize_getPrice("IPFS"),"Thefeeistoolow");
bytes32queryId=oraclize_query("IPFS","json(".toSlice().concat(_hash.toSlice()).toSlice().concat(").title".toSlice()),gasLimit);
authorByHash[keccak256(bytes(_hash))]=msg.sender;
hashByQueryId[queryId]=_hash;emitPostSubmitted(msg.sender,_hash,queryId);returntrue;
}functiongetPriceOfAddingPost()publicviewreturns(uint){returnoraclize_getPrice("IPFS");
}
}

前端使用Web3读取事件,并为给定作者构建所有博客帖子的列表。

降价商品的内容也存储在IPFS上。它允许保留添加新博客帖子的固定费用。我们使用一系列公共IPFS,从我们自己开始。这有意义,尤其是当您从同一节点上传文件时。如果您决定以写入模式运行网关,则还可以以编程方式固定文件(默认情况下,它是只读的)。我们还允许世界杯体育投注平台指定自己的网关。 如果世界杯体育投注平台安装了IPFS Companion,他可以利用自己的节点运行。

BlogEvents.getPastEvents("PostAdded",{fromBlock:0,filter:{author}}).then(events=>{this.setState({addedPosts:events.map(e=>e.returnValues)});
});//...getPost(gatewayIndex=0){this.fetchPostFromIpfs(gateways[gatewayIndex])
.catch(()=>this.retry(gatewayIndex))
}

结论

我们从以太坊智能合约中请求IPFS数据的小实验让我们深入了解IPFS性能,并为更多生产用例的进一步实施奠定了基础。

性能问题唯一顾虑的地方可能是IPNS。IPNS是IPFS的命名系统,允许可变URL。hash对应于对等ID而不是文件或目录内容hash。在版本0.4.14中引入的新IPNS解析器和发布者已经缓解了一些问题。确保你拥有最新版本并使用-enable-namesys-pubsub选项运行守护程序,以便从几乎即时的IPNS更新中受益。

    上一篇:Tomcat介绍、安装配置以及简单的实现Tomcat负载均衡
    下一篇:linux Shell 中grep+wc取值在shell中的结果与手动执行结果不一致的坑
    相关文章
    图文推荐

    关于我们 | 联系我们 | 服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

    版权所有: 红黑--致力于做实用的IT技术学习网站