-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6599 from ethereum/ipfsHash
Add IPFS hash of source files to metadata.
- Loading branch information
Showing
8 changed files
with
509 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
This file is part of solidity. | ||
solidity is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
solidity is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with solidity. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <libdevcore/IpfsHash.h> | ||
|
||
#include <libdevcore/Exceptions.h> | ||
#include <libdevcore/picosha2.h> | ||
#include <libdevcore/CommonData.h> | ||
|
||
using namespace std; | ||
using namespace dev; | ||
|
||
namespace | ||
{ | ||
bytes varintEncoding(size_t _n) | ||
{ | ||
bytes encoded; | ||
while (_n > 0x7f) | ||
{ | ||
encoded.emplace_back(uint8_t(0x80 | (_n & 0x7f))); | ||
_n >>= 7; | ||
} | ||
encoded.emplace_back(_n); | ||
return encoded; | ||
} | ||
|
||
string base58Encode(bytes const& _data) | ||
{ | ||
static string const alphabet{"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"}; | ||
bigint data(toHex(_data, HexPrefix::Add)); | ||
string output; | ||
while (data) | ||
{ | ||
output += alphabet[size_t(data % alphabet.size())]; | ||
data /= alphabet.size(); | ||
} | ||
reverse(output.begin(), output.end()); | ||
return output; | ||
} | ||
} | ||
|
||
bytes dev::ipfsHash(string _data) | ||
{ | ||
if (_data.length() >= 1024 * 256) | ||
BOOST_THROW_EXCEPTION( | ||
DataTooLong() << | ||
errinfo_comment("Ipfs hash for large (chunked) files not yet implemented.") | ||
); | ||
|
||
bytes lengthAsVarint = varintEncoding(_data.size()); | ||
|
||
bytes protobufEncodedData; | ||
// Type: File | ||
protobufEncodedData += bytes{0x08, 0x02}; | ||
if (!_data.empty()) | ||
{ | ||
// Data (length delimited bytes) | ||
protobufEncodedData += bytes{0x12}; | ||
protobufEncodedData += lengthAsVarint; | ||
protobufEncodedData += asBytes(std::move(_data)); | ||
} | ||
// filesize: length as varint | ||
protobufEncodedData += bytes{0x18} + lengthAsVarint; | ||
|
||
// PBDag: | ||
// Data: (length delimited bytes) | ||
size_t protobufLength = protobufEncodedData.size(); | ||
bytes blockData = bytes{0x0a} + varintEncoding(protobufLength) + std::move(protobufEncodedData); | ||
// TODO Handle "large" files with multiple blocks | ||
|
||
// Multihash: sha2-256, 256 bits | ||
bytes hash = bytes{0x12, 0x20} + picosha2::hash256(std::move(blockData)); | ||
return hash; | ||
} | ||
|
||
string dev::ipfsHashBase58(string _data) | ||
{ | ||
return base58Encode(ipfsHash(std::move(_data))); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
This file is part of solidity. | ||
solidity is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
solidity is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with solidity. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <libdevcore/Common.h> | ||
|
||
#include <string> | ||
|
||
namespace dev | ||
{ | ||
|
||
/// Compute the "ipfs hash" of a file with the content @a _data. | ||
/// The output will be the multihash of the UnixFS protobuf encoded data. | ||
/// As hash function it will use sha2-256. | ||
/// The effect is that the hash should be identical to the one produced by | ||
/// the command `ipfs add <filename>`. | ||
bytes ipfsHash(std::string _data); | ||
|
||
/// Compute the "ipfs hash" as above, but encoded in base58 as used by ipfs / bitcoin. | ||
std::string ipfsHashBase58(std::string _data); | ||
|
||
} |
Oops, something went wrong.