溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何將JSON文件存儲(chǔ)在IPFS上

發(fā)布時(shí)間:2021-12-23 10:14:40 來源:億速云 閱讀:427 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“如何將JSON文件存儲(chǔ)在IPFS上”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

如何將JSON文件存儲(chǔ)在IPFS上,并使用Oraclize訪問智能合約中的數(shù)據(jù)呢?

以太坊是一個(gè)成熟的區(qū)塊鏈,使開發(fā)人員能夠創(chuàng)建智能合約,在區(qū)塊鏈上執(zhí)行的程序可以由交易觸發(fā)。人們經(jīng)常將區(qū)塊鏈稱為數(shù)據(jù)庫,但使用區(qū)塊鏈作為數(shù)據(jù)存儲(chǔ)非常昂貴。

以目前的價(jià)格(530美元,4gwei)在以太坊上存儲(chǔ)250GB將花費(fèi)你106,000,000美元。一般來說,我們可以忍受高成本因?yàn)槲覀儯?/p>

  • 不會(huì)在以太坊區(qū)塊鏈上保存那么多數(shù)據(jù)。

  • 區(qū)塊鏈的審查制度,透明度和穩(wěn)健性是值得的。

如果你是以太坊的新手,請(qǐng)查看此 介紹 。

去中心化存儲(chǔ)

IPFS(星際文件系統(tǒng))對(duì)區(qū)塊鏈存儲(chǔ)有一些保證,即去中心化和防篡改,但不比傳統(tǒng)的磁盤空間花費(fèi)更多費(fèi)用。使用EBS 250GB存儲(chǔ)運(yùn)行EC2 t2.micro實(shí)例將花費(fèi)你大約15美元/月。IPFS的一個(gè)獨(dú)特功能是它處理文件的方式。它不使用基于位置的尋址(如域名,IP地址,文件路徑等),而是使用基于內(nèi)容的尋址。將文件(或目錄)添加到IPFS存儲(chǔ)庫后,可以通過其加密哈希來引用它。

$ ipfs add article.json
added Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM article.json
$ ipfs cat Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
{  "title": "This is an awesome title",  "content": "paragraph2\r\n\r\nparagraph3"}
$ curl https://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM{  "title": "This is an awesome title",  "content": "paragraph2\r\n\r\nparagraph3"}

然后,你可以使用IPFS客戶端或任何公共網(wǎng)關(guān)訪問文件。你還可以創(chuàng)建非公共網(wǎng)關(guān),默認(rèn)情況下使其成為可寫(只讀),并實(shí)現(xiàn)授權(quán)方案,以便以編程方式訪問IPFS網(wǎng)絡(luò)。

重要的是要了解IPFS不是一種服務(wù),其他節(jié)點(diǎn)將存儲(chǔ)你的內(nèi)容。如果你的內(nèi)容不受歡迎,如果他們沒有固定哈希(他們不想租用磁盤空間),垃圾收集器會(huì)將其從其他節(jié)點(diǎn)中刪除。只要網(wǎng)絡(luò)上至少有一個(gè)對(duì)等體確實(shí)關(guān)心你的文件并且有興趣存儲(chǔ)它們,網(wǎng)絡(luò)上的其他節(jié)點(diǎn)就可以輕松獲取該文件。即使你的文件從網(wǎng)絡(luò)中消失,也可以在以后再次添加,除非其內(nèi)容發(fā)生更改,否則其地址(哈希)將相同。

IPFS和以太坊智能合約

盡管以太坊協(xié)議沒有提供任何連接到IPFS的本地方式,但我們可以回到像Oraclize這樣的離線解決方案來解決這個(gè)問題。Oraclize允許使用各種數(shù)據(jù)提供智能合約。其中一個(gè)可用的數(shù)據(jù)源是URL。我們可以使用公共網(wǎng)關(guān)從IPFS上的JSON文件中讀取。依靠單個(gè)網(wǎng)關(guān)會(huì)很單薄。我們將要使用的另一個(gè)數(shù)據(jù)源是IPFS。通過使用JSON解析器(它是查詢的一部分)讀取Oraclize智能合約,我們可以在JSON文檔中提取特定字段。

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

如果Oraclize可以在20秒內(nèi)獲取文件,則可以預(yù)期獲得異步請(qǐng)求。如果使用連接良好的節(jié)點(diǎn)上傳文件,則不需要關(guān)注超時(shí)。我們的EC2(歐盟法蘭克福)實(shí)例連接到大約750個(gè)同行。通過公共網(wǎng)關(guān)或本地運(yùn)行守護(hù)進(jìn)程獲取文件幾乎是即時(shí)的。響應(yīng)是異步的,oraclize_query調(diào)用返回查詢id(bytes32)。你可以將其作為來自O(shè)raclize的數(shù)據(jù)的標(biāo)識(shí)符。

function __callback(bytes32 _queryId, string _data) public {  require(msg.sender == oraclize_cbAddress());
  process_data(_data);
}

出于安全原因,我們希望確保只允許Oraclize調(diào)用__callback函數(shù)。

你可以在GitHub上找到博客示例的完整代碼庫: tooploox/ipfs-eth-database

性能和實(shí)施

最初,我很擔(dān)心性能表現(xiàn)。它是否可以像集中服務(wù)發(fā)送響應(yīng)一樣快速地獲取IPFS上托管的JSON文件?結(jié)果令我很驚喜。

$ wrk -d10s https://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
Running 10s test @ https://ipfs.io/ipfs/Qmd4PvCKbFbbB8krxajCSeHdLXQamdt7yFxFxzTbedwiYM
  2 threads and 10 connections
  Thread Stats Avg Stdev Max +/- Stdev
    Latency 59.18ms 24.36ms 307.93ms 94.73%
    Req/Sec 86.34 15.48 101.00 85.57%
  1695 requests in 10.05s, 1.38MB readRequests/sec: 168.72
Transfer/sec: 140.70KB

在我們審查博客時(shí),作者必須在智能合約上調(diào)用addPost時(shí)僅輸入IPFS哈希值。我們使用IPFS和Oraclize從文件中讀取標(biāo)題,以使用以太坊事件存儲(chǔ)它。我們不需要為其他智能合約保留標(biāo)題,因此使用事件對(duì)于我們的用例來說已經(jīng)足夠了。這可能不是最具開創(chuàng)性的例子,但很好地展示了如何優(yōu)化低交易費(fèi)用。

pragma solidity 0.4.24;
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "./lib/usingOraclize.sol";
import "./lib/strings.sol";
contract Blog is usingOraclize, Ownable {  using strings for *;
  mapping(address => string[]) public hashesByAuthor;
  mapping(bytes32 => string) public hashByQueryId;
  mapping(bytes32 => address) public authorByHash;  event PostAdded(address indexed author, string hash, uint timestamp, string title);  event PostSubmitted(address indexed author, string hash, bytes32 queryId);  uint private gasLimit;
  constructor(uint _gasPrice, uint _gasLimit) public {
    setCustomOraclizeGasPrice(_gasPrice);
    setCustomOraclizeGasLimit(_gasLimit);
  }  function getPrice(string _source) public view returns (uint) {    return oraclize_getPrice(_source);
  }  function setCustomOraclizeGasPrice(uint _gasPrice) public onlyOwner {
    oraclize_setCustomGasPrice(_gasPrice);
  }  function setCustomOraclizeGasLimit(uint _gasLimit) public onlyOwner {
    gasLimit = _gasLimit;
  }  function withdraw() public onlyOwner {
    owner.transfer(address(this).balance);
  }
  function __callback(bytes32 _queryId, string _title) public {
    require(msg.sender == oraclize_cbAddress());
    require(bytes(hashByQueryId[_queryId]).length != 0);    string memory hash = hashByQueryId[_queryId];
    address author = authorByHash[keccak256(bytes(hash))];
    hashesByAuthor[author].push(hash);    emit PostAdded(author, hash, now, _title);
  }  function addPost(string _hash) public payable returns (bool) {
    require(authorByHash[keccak256(bytes(_hash))] == address(0), "This post already exists");
    require(msg.value >= oraclize_getPrice("IPFS"), "The fee is too low");
    bytes32 queryId = oraclize_query("IPFS", "json(".toSlice().concat(_hash.toSlice()).toSlice().concat(").title".toSlice()), gasLimit);
    authorByHash[keccak256(bytes(_hash))] = msg.sender;
    hashByQueryId[queryId] = _hash;    emit PostSubmitted(msg.sender, _hash, queryId);    return true;
  }  function getPriceOfAddingPost() public view returns (uint) {    return oraclize_getPrice("IPFS");
  }
}

前端使用Web3讀取事件,并為給定作者構(gòu)建所有博客帖子的列表。

降價(jià)商品的內(nèi)容也存儲(chǔ)在IPFS上。它允許保留添加新博客帖子的固定費(fèi)用。我們使用一系列公共IPFS,從我們自己開始。這有意義,尤其是當(dāng)您從同一節(jié)點(diǎn)上傳文件時(shí)。如果您決定以寫入模式運(yùn)行網(wǎng)關(guān),則還可以以編程方式固定文件(默認(rèn)情況下,它是只讀的)。我們還允許用戶指定自己的網(wǎng)關(guān)。 如果用戶安裝了IPFS Companion,他可以利用自己的節(jié)點(diǎn)運(yùn)行。

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))
}

“如何將JSON文件存儲(chǔ)在IPFS上”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI