

我们创造了一个中心化的数字世界,它依赖于服务器上运行的服务。这些服务器通常集中提供服务以及数据基础设施。如果服务或数据存储失败,则会对提供服务本身产生风险。除此之外,防火墙还可以阻止人们获取信息。那有什么其他选择呢?IPFS 提供了一种将文件分发到世界各地的方法,在这种方法中,我们使用哈希值(CID—内容标识符—是文件的SHA-256哈希版本)来标识内容。这一定程度上简化了我们创建的复杂URL结构。
那么,为什么我需要服务来定位磁盘上某个地方的文件,然后将其与复杂的URL匹配呢?为什么我不能给内容一个标识符,让互联网找到它呢?
因此,我正在将我的密码挑战基础设施的大部分都转向IPFS和智能合约。这意味着我不需要在服务器上存储文件或在服务器上运行代码来生成挑战。现在让我们以Pigpen密码为例。目前,我使用我的服务器来生成挑战,并为每个Pigpen图形提供图形来源:

IPFS
IPFS使用P2P方法实现分布式基础设施,没有中心化服务器。就像Torrent网络一样,它被定义为抗审查的,IPFS可以被比作我们使用内容地址超链接的Web,但是在这里一个单一的BitTorrent集群在一个Git库中交换的对象。
IPFS将文件分解为区块或区块与跟踪,并使用Merkle DAG(直接无环图)来定义文件的版本控制和分布式哈希表。在传统的区块链基础结构中,我们按顺序存储交易。这可能需要一些时间来通过构建模块来达成共识。使用DAG,每个交易都会成为一个区块,从而加快了共识机制的速度。Sergio Demian Lerner指出,在DAG中没有固定的区块,每个交易都有自己的工作证明。在这个框架中,他为最近的交易定义了快速缓存的用法,以及旧的交易不能作为引用的用法。
IPFS 存储
因此,让我们从IPFS中获取图形,并使用智能合约生成挑战。首先,我们需要运行一个IPFS桌面,并“种”图形(‘a.png’, ‘b.png’,等等):

我们可以用CID回调图形,或者使用一个源网关。这已将“a”作为:
QmcizbQqy4A9HRUEA34aiBSzbpk6BHJFDjAJWMvrKQRUyA
然后我们可以访问:
A ‘ b ‘的是:
QmcVC9hK9CDKW9RC5aBNFjF521XyDCfiPR3zzzQ84NZGXy
然后我们可以访问:
智能合约
现在我们将创建一个智能合约。为此,我们将随机生成一个单词,然后将每个字符映射到IPFS存储:
pragma solidity ^0.8.0;// SPDX-License-Identifier: MITcontract Ciphers { string [59] words =["accepting", "active", "added", "angle", "area", "authors", "besides","box","category","common", "company","compare","complaints","complete","complicate", "concern","concrete","consider","consistency", "continuous","corners","course","crisis","cross","daily", "danger","decide","default","department","depth","detail", "dictionary","disadvantage","dislike","displays","documented", "dream","drive","earth","education","emergency", "enjoy","eraser","evidence","examine","exercise", "exists","expand","expanded","expanding","expands","expansion", "face", "facilities", "facility","fact","factor", "facts", "igloo"]; function pigpen_cipher() view public returns (string memory) { string [26] memory ipfs=["QmcizbQqy4A9HRUEA34aiBSzbpk6BHJFDjAJWMvrKQRUyA", "QmcVC9hK9CDKW9RC5aBNFjF521XyDCfiPR3zzzQ84NZGXy", "QmfP33Mde6wLXphucyV6Z3em8HjHhdftEBgJ4PDcfuNzgu", "QmPXZXszrGn2c1pcL2UNK3UfqW6DYaLHZsicYo5Gktkj4W", "QmWBcdmDzdQNkuNneaVgEWpCmHyacSDyUYGvWWKdWwmY5F", "QmVhddtfRsXnJyiuQbXgZcKoGyDVCqnNvcyVEBKZqqLMrR", "Qmdvvx2Ld8Hm4t2zKgwygJkSn95MhL1ydz2mJNcbUuJV3X", "QmTKsT2MSFhYNMgF6dKALHHeXvgfM5opdqE1VeWcSDvbad", "QmR7StEGgVkURcbiwK2KBEq7kstwzawAQmp7tuAQ37dTBT", "QmeUqUVkDqyHxGbugrc97w7JuyRvbh3C3CYwMPc31C6Sqa", "QmamDWzzAr3XvvvHk6DbRk7n7tUVsaXYorHnJJBiVMbtNS", "QmPVn2BEyKCBKc1SRK9KicFqyW9Sg7ohAypSBZEPJhMrqu", "QmbqEVE1QWePs9U8wkDs8ciZuZYVjA6fZN64rJq3GFA7oj", "QmYZuznL9juXoFs7AiRysPqkaZxb6cskKrd7ze6zReg2tW", "QmPAw8SpwvUQQxf3SfcKAmVvpko6bETBYeRJShCkYxMDef", "QmfTyFLuwRxEYrj2zpu6sMsCCTJV6fh7QJphHCEHpCL5T5", "QmQKp5QCw2TRr9dhyVFPKpGEErjSx7L6KTEhgHs7uYgWgN", "QmapjseB9ZvajzZX39RHGJy3X1ny3t6wVCdruiNLtAcQLg", "QmPyy7kn3TqT5EMJLKaumHxxpuQ7387Cyxvnc79pRcg44R", "QmV1rgTWd8QBW8ZMZhUU26Jz3vfUnT6A2kBqwU2rnJWbUe", "QmPnwDGtzWefzXwFcBV4TXWQ1cvbXsgMYAs1aRpotjy5WD", "Qmf9BzmSqj7UJ9XBv9pKGEa8VHb3J4aJYHmCStopgKEBng", "QmcSw7WNyvKTLuxLzFq4vCisw5u3eJN218K8ioHcGug6yR", "QmYXaP2QMLpVsGpugKdTzYQ1V4JbnULnRDqmHAWMxdyJFy", "Qmd5ZeGU5cJFUasQBWr7VvXbbPUWQcYnWUUQQVYkyk6XT6", "QmWWd8DbkjJmkbD8b6xjr1X4Ped2ufokgatyp2vS92hSV8" ]; bytes memory word=bytes(words[random(words.length,0)]); string memory rtn="Find the plaintext for the Pigpen code of: "; for (uint256 i=0;i<word.length;i++) { uint256 pos=uint8(word[i])-uint8(97); rtn=string(abi.encodePacked(rtn,"<img src='https://ipfs.io/ipfs/",ipfs[pos],"' style='height: 50px;'> " )); } rtn= string(abi.encodePacked(rtn, "\n\nThe answer is:\n",word)); return string(rtn); } function morse_code() view public returns (string memory) { string [26] memory morse= ["(.-)","(-...)","(-.-.)","(-..)","(.)","(..-.)","(- -.)","(....)", "(..)","(.- - -)","(-.-)","(.-..)","(- -)","(-.)","(- - -)","(.- -.)","(- -.-)", "(.-.)","(...)","(-)","(..-)","(...-)","(.- -)","(-..-)","(-.- -)","(- -..)"]; bytes memory word=bytes(words[random(words.length,0)]); string memory rtn="Find the plaintext for the Morse code of: "; for (uint256 i=0;i<word.length;i++) { uint256 pos=uint8(word[i])-uint8(97); rtn=string(abi.encodePacked(rtn, (morse[pos]))); } rtn= string(abi.encodePacked(rtn, "\n\nThe mapping is:\n")); rtn=string(abi.encodePacked(rtn, word)); return string(rtn); } function random(uint number,uint i) view internal returns(uint){ return uint(keccak256(abi.encodePacked(block.timestamp,block.difficulty, msg.sender,uint(i)))) % number; } }
到IPFS存储的映射是用以下字符串数组定义的:
string [26] ipfs=["QmcizbQqy4A9HRUEA34aiBSzbpk6BHJFDjAJWMvrKQRUyA","QmcVC9hK9CDKW9RC5aBNFjF521XyDCfiPR3zzzQ84NZGXy","QmfP33Mde6wLXphucyV6Z3em8HjHhdftEBgJ4PDcfuNzgu","QmPXZXszrGn2c1pcL2UNK3UfqW6DYaLHZsicYo5Gktkj4W",];
现在我们可以随机选择一个单词,然后确定它在字母表中的位置(pos),然后将其映射到Pigpen图形:
function pigpen_cipher() view public returns (string memory) { bytes memory word=bytes(words[random(words.length,0)]); string memory rtn="Find the plaintext for the Pigpen code of: "; for (uint256 i=0;i<word.length;i++) { uint256 pos=uint8(word[i])-uint8(97); rtn=string(abi.encodePacked(rtn, "<img src='https://ipfs.io/ipfs/",ipfs[pos],"' style='height: 50px;'> " )); }rtn= string(abi.encodePacked(rtn, "\n\nThe answer is:\n",word));return string(rtn);}
首先,我们将创建智能合约并编译它:

然后我们就可以用ganache开始我们的区块链了:

然后在本地部署我们的合约:

然后我们看到矿工们收取了一些gas:

现在我们将测试:

代码是:
Find the plaintext for the Pigpen code of: <img src='https://ipfs.io/ipfs/QmPXZXszrGn2c1pcL2UNK3UfqW6DYaLHZsicYo5Gktkj4W' style='height: 50px;'> <img src='https://ipfs.io/ipfs/QmR7StEGgVkURcbiwK2KBEq7kstwzawAQmp7tuAQ37dTBT' style='height: 50px;'> <img src='https://ipfs.io/ipfs/QmPyy7kn3TqT5EMJLKaumHxxpuQ7387Cyxvnc79pRcg44R' style='height: 50px;'> <img src='https://ipfs.io/ipfs/QmfTyFLuwRxEYrj2zpu6sMsCCTJV6fh7QJphHCEHpCL5T5' style='height: 50px;'> <img src='https://ipfs.io/ipfs/QmPVn2BEyKCBKc1SRK9KicFqyW9Sg7ohAypSBZEPJhMrqu' style='height: 50px;'> <img src='https://ipfs.io/ipfs/QmcizbQqy4A9HRUEA34aiBSzbpk6BHJFDjAJWMvrKQRUyA' style='height: 50px;'> <img src='https://ipfs.io/ipfs/Qmd5ZeGU5cJFUasQBWr7VvXbbPUWQcYnWUUQQVYkyk6XT6' style='height: 50px;'> <img src='https://ipfs.io/ipfs/QmPyy7kn3TqT5EMJLKaumHxxpuQ7387Cyxvnc79pRcg44R' style='height: 50px;'> The answer is: displays
如果我们把它加载到浏览器中,我们会得到:

部署到以太坊测试网络
一旦我们在本地测试了它,我们就可以将它转移到以太坊测试网络。在本例中,我们将使用Ropsten测试网络。然后我们将部署环境更改为 “ Injected Web3 ”,然后链接一个Metamask钱包,然后部署:

然后,我们将等待矿工“拿起”智能合约:

然后:

然后我们可以查看新合约的交易:

接下来我们可以查看合约:

我们现在需要验证合约:

然后:

然后粘贴代码来验证:

然后得到一个成功的部署:

现在我们可以测试:

智能合约在这里:
结论
IPFS提供了一种更有弹性、更快的探索内容来源的方法。智能合约也支持更分布式的方式。总的来说,IPFS提供了一种很好的访问内容的方法,但是仍然有一些问题需要解决,比如将加密集成到文件中,以及确保文件可以被删除。
关于
ChinaDeFi – ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。
Layer 2道友 – 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”。
