update_directory_hashes finds a vanity number on its own now
This commit is contained in:
parent
748e8368d5
commit
316c1e55a1
|
@ -1 +1 @@
|
|||
var ipfs_directory_hashes={"vanity_text":"soy","vanity_number":1891,"tree":{"Links":[{"Name":".ipfsignore","Hash":"QmWMeSQQxuSYMddVwJGrnn12zrX1TTW7ueZbhZdaZ64Wr1","Size":14},{"Name":"directory_hashes.js","Hash":"","Size":0},{"Name":"index.html","Hash":"QmSGG1iXXNkpLWeKmmZaqnEaUD9Thpkq3ysvzg7Y5VJVBN","Size":853},{"Name":"ipfs.js","Hash":"QmUyp8avhb7JJRuvCMccocta99vfpphp3sWRHD5JpiJVBS","Size":10701},{"Name":"ipfs_self_hash.js","Hash":"QmQNg8yy2PKKKrMbNDAfTALxrU9U1Lv7M6CX9tb5sWQFfL","Size":3099},{"Name":"lzw.js","Hash":"QmP2CsTDmyR9h5UrXJgXGswyMhiSHBZkQKLszdgh9Eb8Rk","Size":2034},{"Name":"quine.js","Hash":"QmcHWTtgH53KkaSsWEvTxKDuuTNxipC3iJyebS3BBuF21B","Size":3099},{"Name":"s","Hash":"QmZ1aMjVWAowuu7jYXU2uYLTwDiKSnh5yCeHTenP3ctFd6","Size":949},{"Name":"sha256.js","Hash":"QmciGVnQsvn5TFczbrte6JkZ81r9s1MXgFQW1kv2ZXErpM","Size":8477},{"Name":"update_directory_hashes.sh","Hash":"QmePjEEJnG6N569H3Fn9DayRHBHrkhvdWwZaoJtnKkf9Bt","Size":1113},{"Name":"update_quine.sh","Hash":"QmVZY9bqdiopA4BaxNRwJr5AWLbE8ikb19dAJoKCNENNez","Size":3029}],"Data":"\b\u0001"}};
|
||||
var ipfs_directory_hashes={"vanity_text":"soy","vanity_number":10448,"tree":{"Links":[{"Name":".ipfsignore","Hash":"QmWMeSQQxuSYMddVwJGrnn12zrX1TTW7ueZbhZdaZ64Wr1","Size":14},{"Name":"directory_hashes.js","Hash":"","Size":0},{"Name":"find_vanity.js","Hash":"QmYcaVuBSCY3CbuXut23kQYpKHN6HuDG6F8mAHeRifdmXZ","Size":229},{"Name":"index.html","Hash":"QmZaXPFa47VxJNsNcaejw7R9GNPGCF5FjkSCDrvrmBAeP9","Size":553},{"Name":"lzw.js","Hash":"QmP2CsTDmyR9h5UrXJgXGswyMhiSHBZkQKLszdgh9Eb8Rk","Size":2034},{"Name":"micro_ipfs.js","Hash":"Qmefnv6QiZqcqAEh8G1gsVQi4hAoXxwkXjWxL3jxjx1Kk7","Size":15370},{"Name":"quine.js","Hash":"QmcHWTtgH53KkaSsWEvTxKDuuTNxipC3iJyebS3BBuF21B","Size":3099},{"Name":"sha256.js","Hash":"QmRhgx5Fq4JqfCgsPcMxNSYwt8M9WRBkec9omPWzJ7gdwL","Size":8553},{"Name":"update_directory_hashes.sh","Hash":"QmYmJcAQpxWb4TbLw2UwM92w6sVfrQMCKitgn8Qg62T8zU","Size":1473},{"Name":"update_quine.sh","Hash":"QmVZY9bqdiopA4BaxNRwJr5AWLbE8ikb19dAJoKCNENNez","Size":3029}],"Data":"\b\u0001"}}; if (typeof module != 'undefined') { module.exports = { ipfs_directory_hashes: ipfs_directory_hashes }; }
|
||||
|
|
3
find_vanity.js
Normal file
3
find_vanity.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const directory_hashes = require('./directory_hashes.js');
|
||||
const micro_ipfs = require('./micro_ipfs.js');
|
||||
console.log(micro_ipfs.ipfs_self_hash.find_vanity_node(null, 'soy', 0, directory_hashes.ipfs_directory_hashes));
|
15
index.html
15
index.html
|
@ -8,17 +8,12 @@
|
|||
<script src="directory_hashes.js"></script>
|
||||
<script src="lzw.js"></script>
|
||||
<script src="sha256.js"></script>
|
||||
<script src="ipfs.js"></script>
|
||||
<script src="ipfs_self_hash.js"></script>
|
||||
<script src="micro_ipfs.js"></script>
|
||||
<script>
|
||||
function my_show_link(root, good_vanity) {
|
||||
console.log('cccc');
|
||||
//document.getElementById('self-src').innerText = hexStringToString(root.src3); // only with the quine version
|
||||
document.getElementById('ipfs-link').innerHTML = '<a href="ipfs://' + root.hash + '"">Permalink to this file: ipfs://'+root.hash+'</a> vanity = <span id="ipfs-vanity">' + good_vanity + "</span>";
|
||||
}
|
||||
console.log('aaaaa');
|
||||
ipfs_self_hash(my_show_link);
|
||||
console.log('bbbbb');
|
||||
(function() {
|
||||
var hash = ipfs_self_hash.get_link();
|
||||
document.getElementById('ipfs-link').innerHTML = '<a href="ipfs://' + hash + '"">Permalink to this file: ipfs://'+hash+'</a>';
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
var ipfs_self_hash = (function() {
|
||||
var ipfs = micro_ipfs;
|
||||
var get_root_with_vanity = function(vanity_attempt) {
|
||||
var find_link_entry = function() {
|
||||
for (var i = 0; i < ipfs_directory_hashes.tree.Links.length; i++) {
|
||||
if (ipfs_directory_hashes.tree.Links[i].Name == 'directory_hashes.js') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
var foo_link_entry = find_link_entry();
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Hash = "";
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Size = 0;
|
||||
ipfs_directory_hashes.vanity_number = vanity_attempt;
|
||||
|
||||
// TODO: using JSON.stringify to recreate the file is more brittle, better store the stringified version as a hex string, and then decode it?
|
||||
var file_directory_hashes = 'var ipfs_directory_hashes=' + JSON.stringify(ipfs_directory_hashes) + ';\n';
|
||||
var foo = ipfs.hashWithLinks(16, {
|
||||
"Links": [],
|
||||
"isFile": true,
|
||||
"File": ipfs.utf8StringToHex(file_directory_hashes)
|
||||
});
|
||||
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Hash = foo.hash;
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Size = foo.block.length;
|
||||
|
||||
root = ipfs.hashWithLinks(32, ipfs_directory_hashes.tree);
|
||||
return root;
|
||||
}
|
||||
|
||||
var expected_vanity_attempt = 32*32*32;
|
||||
var max_vanity_attempt = expected_vanity_attempt*10;
|
||||
function find_vanity(old_root, vanity_text, vanity_attempt, callback) {
|
||||
var root = get_root_with_vanity(vanity_attempt);
|
||||
console.log(root.hash, vanity_attempt, vanity_text);
|
||||
if (vanity_attempt > max_vanity_attempt) {
|
||||
// give up:
|
||||
root = get_root_with_vanity(ipfs_directory_hashes.vanity_number)
|
||||
callback(root, 'timeout');
|
||||
} else {
|
||||
if (root.hash[root.hash.length-1] == vanity_text[2]) {
|
||||
callback(old_root, '… ' + vanity_attempt + ' (' + Math.floor(100*vanity_attempt/expected_vanity_attempt) + '%)');
|
||||
if (root.hash[root.hash.length-2] == vanity_text[1] && root.hash[root.hash.length-3] == vanity_text[0]) {
|
||||
callback(root, vanity_attempt);
|
||||
} else {
|
||||
window.setTimeout(function() { find_vanity(old_root, vanity_text, vanity_attempt + 1, callback); }, 0);
|
||||
}
|
||||
} else {
|
||||
window.setTimeout(function() { find_vanity(old_root, vanity_text, vanity_attempt + 1, callback); }, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function main(show_link) {
|
||||
console.log('ipfs_self_hash a');
|
||||
var root = get_root_with_vanity(ipfs_directory_hashes.vanity_number);
|
||||
var vanity_text = ipfs_directory_hashes.vanity_text;
|
||||
|
||||
console.log('ipfs_self_hash b');
|
||||
if (root.hash[root.hash.length-1] == vanity_text[2] && root.hash[root.hash.length-2] == vanity_text[1] && root.hash[root.hash.length-3] == vanity_text[0]) {
|
||||
// vanity check is ok
|
||||
console.log('ipfs_self_hash c');
|
||||
show_link(root, ipfs_directory_hashes.vanity_number);
|
||||
} else {
|
||||
// Brute-force to try to find a number that gives the desired last 3 characters
|
||||
console.log('ipfs_self_hash d');
|
||||
show_link(root, '…');
|
||||
find_vanity(root, vanity_text, 0, show_link);
|
||||
}
|
||||
}
|
||||
|
||||
return main;
|
||||
})();
|
|
@ -1,3 +1,6 @@
|
|||
// for nodejs
|
||||
if (typeof sha256 == 'undefined' && typeof require != 'undefined') { try { sha256 = require('./sha256.js').sha256; } catch (e) {console.log(e);} }
|
||||
|
||||
var micro_ipfs = (function() {
|
||||
var hexVarintToInteger = function(str) {
|
||||
var s = String(str);
|
||||
|
@ -16,7 +19,7 @@ var micro_ipfs = (function() {
|
|||
offset *= Math.pow(2,7);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
};
|
||||
|
||||
var hexStringToIntegerList = function(str) {
|
||||
var s = String(str);
|
||||
|
@ -25,7 +28,7 @@ var micro_ipfs = (function() {
|
|||
result[i/2] = parseInt(s.substring(i, i+2), 16);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var hexStringToString = function(str) {
|
||||
var s = String(str);
|
||||
|
@ -34,7 +37,7 @@ var micro_ipfs = (function() {
|
|||
result += String.fromCharCode(parseInt(s.substring(i, i+2), 16));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var sha256IntegerListToMultihash = function(base, lst) {
|
||||
// 0x20 is the length of the hash.
|
||||
|
@ -51,7 +54,7 @@ var micro_ipfs = (function() {
|
|||
result[j+i] = lst[j];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var integerListToLowercaseBase16Multibase = function(lst) {
|
||||
var result = '';
|
||||
|
@ -61,7 +64,7 @@ var micro_ipfs = (function() {
|
|||
result += hex;
|
||||
}
|
||||
return 'f' + result;
|
||||
}
|
||||
};
|
||||
|
||||
var int8ListToBitList = function(lst) {
|
||||
var result = [];
|
||||
|
@ -76,7 +79,7 @@ var micro_ipfs = (function() {
|
|||
result[i*8+7] = (lst[i] & 1) ? 1 : 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var base32StringToBitList = function(str) {
|
||||
var baseChars = 'abcdefghijklmnopqrstuvwxyz234567';
|
||||
|
@ -94,7 +97,7 @@ var micro_ipfs = (function() {
|
|||
result[i*5+4] = (part & 1) ? 1 : 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// https://gist.github.com/diafygi/90a3e80ca1c2793220e5/, license: wtfpl
|
||||
var from_b58 = function(S,A){var d=[],b=[],i,j,c,n;for(i in S){j=0,c=A.indexOf(S[i]);if(c<0)return undefined;c||b.length^i?i:b.push(0);while(j in d||c){n=d[j];n=n?n*58+c:c;c=n>>8;d[j]=n%256;j++}}while(j--)b.push(d[j]);return new Uint8Array(b)};
|
||||
|
@ -109,7 +112,7 @@ var micro_ipfs = (function() {
|
|||
result += hex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var integerListToLowercaseBase32Multibase = function(lst) {
|
||||
var baseChars = 'abcdefghijklmnopqrstuvwxyz234567';
|
||||
|
@ -122,7 +125,7 @@ var micro_ipfs = (function() {
|
|||
result += baseChars[part];
|
||||
}
|
||||
return 'b' + result;
|
||||
}
|
||||
};
|
||||
|
||||
var base32StringToBase16LowercaseMultibase = function(str) {
|
||||
var baseChars = '0123456789abcdef';
|
||||
|
@ -135,7 +138,7 @@ var micro_ipfs = (function() {
|
|||
result += baseChars[part];
|
||||
}
|
||||
return 'f' + result;
|
||||
}
|
||||
};
|
||||
|
||||
var integerToHexVarint = function(i) {
|
||||
// This function takes a JavaScript integer and returns a hexadecimal string representing that integer encoded as a protobuf varint according to the rules explained at
|
||||
|
@ -171,7 +174,7 @@ var micro_ipfs = (function() {
|
|||
result += hex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var ipfsBlockWithLinks = function(object) {
|
||||
// object should be an { "Links": links, "Data": hex-encoded string } object
|
||||
|
@ -277,7 +280,7 @@ var micro_ipfs = (function() {
|
|||
result += encodedData;
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
var ipfsHashWithLinks = function(base, object) {
|
||||
var block = hexStringToIntegerList(ipfsBlockWithLinks(object));
|
||||
|
@ -290,10 +293,104 @@ var micro_ipfs = (function() {
|
|||
} else {
|
||||
return { "hash" : integerListToLowercaseBase32Multibase(hash), "block" : block };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
utf8StringToHex: utf8StringToHex,
|
||||
hashWithLinks: ipfsHashWithLinks
|
||||
}
|
||||
})();
|
||||
};
|
||||
})();
|
||||
|
||||
var ipfs_self_hash = (function() {
|
||||
var ipfs = micro_ipfs;
|
||||
var get_root_with_vanity = function(vanity_attempt, ipfs_directory_hashes) {
|
||||
var find_link_entry = function() {
|
||||
for (var i = 0; i < ipfs_directory_hashes.tree.Links.length; i++) {
|
||||
if (ipfs_directory_hashes.tree.Links[i].Name == 'directory_hashes.js') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
var foo_link_entry = find_link_entry();
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Hash = "";
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Size = 0;
|
||||
ipfs_directory_hashes.vanity_number = vanity_attempt;
|
||||
|
||||
// TODO: using JSON.stringify to recreate the file is more brittle, better store the stringified version as a hex string, and then decode it?
|
||||
var file_directory_hashes = 'var ipfs_directory_hashes=' + JSON.stringify(ipfs_directory_hashes) + '; if (typeof module != \'undefined\') { module.exports = { ipfs_directory_hashes: ipfs_directory_hashes }; }\n';
|
||||
var foo = ipfs.hashWithLinks(16, {
|
||||
"Links": [],
|
||||
"isFile": true,
|
||||
"File": ipfs.utf8StringToHex(file_directory_hashes)
|
||||
});
|
||||
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Hash = foo.hash;
|
||||
ipfs_directory_hashes.tree.Links[foo_link_entry].Size = foo.block.length;
|
||||
|
||||
root = ipfs.hashWithLinks(32, ipfs_directory_hashes.tree);
|
||||
return root;
|
||||
};
|
||||
|
||||
var expected_vanity_attempt = 32*32*32;
|
||||
var max_vanity_attempt = expected_vanity_attempt*10;
|
||||
function find_vanity_node(old_root, vanity_text, vanity_attempt, ipfs_directory_hashes) {
|
||||
while (true) {
|
||||
if (vanity_attempt > max_vanity_attempt) {
|
||||
// give up:
|
||||
return null;
|
||||
} else {
|
||||
var root = get_root_with_vanity(vanity_attempt, ipfs_directory_hashes);
|
||||
if (root.hash[root.hash.length-1] == vanity_text[2] && root.hash[root.hash.length-2] == vanity_text[1]) {
|
||||
console.error(vanity_attempt + ' (' + Math.floor(100*vanity_attempt/expected_vanity_attempt) + '%)');
|
||||
if (root.hash[root.hash.length-3] == vanity_text[0]) {
|
||||
return vanity_attempt;
|
||||
}
|
||||
}
|
||||
vanity_attempt++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function find_vanity_browser(old_root, vanity_text, vanity_attempt, callback, ipfs_directory_hashes) {
|
||||
var root = get_root_with_vanity(vanity_attempt, ipfs_directory_hashes);
|
||||
if (vanity_attempt > max_vanity_attempt) {
|
||||
// give up:
|
||||
root = get_root_with_vanity(ipfs_directory_hashes.vanity_number, ipfs_directory_hashes)
|
||||
callback(root, 'timeout', false);
|
||||
} else {
|
||||
if (root.hash[root.hash.length-1] == vanity_text[2]) {
|
||||
callback(old_root, '… ' + vanity_attempt + ' (' + Math.floor(100*vanity_attempt/expected_vanity_attempt) + '%)', false);
|
||||
if (root.hash[root.hash.length-2] == vanity_text[1] && root.hash[root.hash.length-3] == vanity_text[0]) {
|
||||
callback(root, vanity_attempt, true);
|
||||
} else {
|
||||
window.setTimeout(function() { find_vanity_browser(old_root, vanity_text, vanity_attempt + 1, callback, ipfs_directory_hashes); }, 0);
|
||||
}
|
||||
} else {
|
||||
window.setTimeout(function() { find_vanity_browser(old_root, vanity_text, vanity_attempt + 1, callback, ipfs_directory_hashes); }, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var debug = function(show_link) {
|
||||
var root = get_root_with_vanity(ipfs_directory_hashes.vanity_number, ipfs_directory_hashes);
|
||||
var vanity_text = ipfs_directory_hashes.vanity_text;
|
||||
|
||||
if (root.hash[root.hash.length-1] == vanity_text[2] && root.hash[root.hash.length-2] == vanity_text[1] && root.hash[root.hash.length-3] == vanity_text[0]) {
|
||||
// vanity check is ok
|
||||
show_link(root, ipfs_directory_hashes.vanity_number, true);
|
||||
} else {
|
||||
// Brute-force to try to find a number that gives the desired last 3 characters
|
||||
show_link(root, '…', false);
|
||||
find_vanity_browser(root, vanity_text, 0, show_link, ipfs_directory_hashes);
|
||||
}
|
||||
};
|
||||
|
||||
var get_link = function get_link() {
|
||||
var root = get_root_with_vanity(ipfs_directory_hashes.vanity_number, ipfs_directory_hashes);
|
||||
return root.hash;
|
||||
};
|
||||
|
||||
return { get_link: get_link, find_vanity_browser: find_vanity_browser, find_vanity_node: find_vanity_node };
|
||||
})();
|
||||
|
||||
if (typeof module != 'undefined') { module.exports = { micro_ipfs : micro_ipfs, ipfs_self_hash : ipfs_self_hash }; }
|
|
@ -200,3 +200,5 @@ var sha256 = (function() {
|
|||
}
|
||||
return hash;
|
||||
})();
|
||||
|
||||
if (typeof module != 'undefined') { module.exports = { sha256 : sha256 }; }
|
|
@ -3,28 +3,31 @@
|
|||
set -euET -o pipefail
|
||||
|
||||
vanity_text="${1:-xyz}"
|
||||
vanity_number="${2:-0}"
|
||||
directory="${3:-.}"
|
||||
directory="${2:-.}"
|
||||
|
||||
temp_file="$(mktemp)"
|
||||
hexdump="$(mktemp)"
|
||||
|
||||
if test -z "$directory" -o "$directory" = "-h" -o "$directory" = "--help"; then
|
||||
echo 'Usage: ./update-hashes.sh vanity-text vanity-number [path/to/directory]'
|
||||
if test -z "$vanity_text" -o "$vanity_text" = "-h" -o "$vanity_text" = "--help"; then
|
||||
echo 'Usage: ./update-hashes.sh vanity-text [path/to/directory]'
|
||||
echo 'The given directory should contain a file named meta.js, which will be overwritten.'
|
||||
echo 'The vanity text should be three letters, which will appear at the end of your website'\''s hash'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf %s 'var ipfs_directory_hashes=' >> "$temp_file"
|
||||
|
||||
# TODO: use ipfs dag get instead of ipfs object get
|
||||
partial_hash="$(ipfs add --ignore-rules-path .ipfsignore --pin=false --hidden -Qr "$directory")"
|
||||
ipfs object get "$partial_hash" \
|
||||
| jq '.Links |= map(if .Name == "directory_hashes.js" then { "Name": .Name, "Hash": "", "Size": 0 } else . end)' \
|
||||
| jq -r '{vanity_text:"'"$vanity_text"'", vanity_number:'$vanity_number',tree:.} | tostring' >> "$temp_file"
|
||||
sed -i -e 's/$/;/' "$temp_file"
|
||||
foo="$(ipfs object get "$partial_hash" | jq '.Links |= map(if .Name == "directory_hashes.js" then { "Name": .Name, "Hash": "", "Size": 0 } else . end)' )"
|
||||
|
||||
mv "$temp_file" "$directory"/directory_hashes.js
|
||||
write_directory_hashes() {
|
||||
contents="$(printf %s "$foo" | jq -r '{vanity_text:"'"$vanity_text"'", vanity_number:'$1',tree:.} | tostring')"
|
||||
printf 'var ipfs_directory_hashes=%s; if (typeof module != '\''undefined'\'') { module.exports = { ipfs_directory_hashes: ipfs_directory_hashes }; }\n' "$contents" > "$directory"/directory_hashes.js
|
||||
}
|
||||
|
||||
write_directory_hashes "0"
|
||||
vanity_number="$(node find_vanity.js)"
|
||||
printf 'Found vanity number: %s\n' $vanity_number
|
||||
write_directory_hashes "$vanity_number"
|
||||
|
||||
echo "The hash given by the page should be:"
|
||||
ipfs cid base32 "$(ipfs add --ignore-rules-path .ipfsignore --hidden -Qr "$directory")"
|
||||
printf 'ipfs://%s\n' "$(ipfs cid base32 "$(ipfs add --ignore-rules-path .ipfsignore --hidden -Qr "$directory")")"
|
||||
|
|
Loading…
Reference in New Issue
Block a user