Skip to content

Instantly share code, notes, and snippets.

@clemensgg
Last active November 16, 2022 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save clemensgg/579983404afd4e906a4419fe4e81d100 to your computer and use it in GitHub Desktop.
Save clemensgg/579983404afd4e906a4419fe4e81d100 to your computer and use it in GitHub Desktop.
GOC_differing_valsets
// Gist depracted in favour of https://github.com/clemensgg/game-of-chains/
'use strict';
import axios from 'axios';
import { createHash } from 'crypto';
import fs from 'fs/promises';
/* ------------------------ CONFIG ------------------------ */
const provider = {
"id": "provider",
"lcd": "http://0.0.0.0:26619",
"start_height": 140100,
"last_height": 0,
"valset_data": [["height", "hash","total_vp"]]
}
const consumer = {
"id": "sputnik",
"lcd": "http://0.0.0.0:26629",
"start_height": 86800,
"last_height": 0,
"valset_data": [["height", "hash", "total_vp"]]
}
/* -------------------------------------------------------- */
// generate sha256 hash
function hash(string) {
return createHash('sha256').update(string).digest('hex');
}
// async write file
async function writeFile(path, data) {
try {
await fs.writeFile(path, data);
}
catch (e) {
console.log('> ERROR writing blacklist to filesystem');
console.log(e.data);
return false;
}
return true;
}
// save all valset records
async function dumpValsetRecords() {
let cc_file = './export/' + consumer.id + '_valsets_' + consumer.last_height + '.csv'
let pc_file = './export/' + provider.id + '_valsets_' + provider.last_height + '.csv'
let csvContent = ""
+ consumer.valset_data.map(e => e.join(",")).join("\n");
let res = await writeFile(cc_file, csvContent);
if (res) {
console.log('saved CONSUMER set to file: ' + cc_file);
}
csvContent = ""
+ provider.valset_data.map(e => e.join(",")).join("\n");
res = await writeFile(pc_file, csvContent);
if (res) {
console.log('saved PROVIDER set to file: ' + pc_file);
}
return true;
}
// fetch latest valset
async function fetchLatestValset(chain) {
try {
var res = await axios.get(chain.lcd + '/validatorsets/latest');
}
catch (e) {
console.log(e.data);
return false;
}
return res.data.result;
}
// append new valset of chain
function appendSet(chain, set) {
Object.entries(set.validators).forEach(validator => {
const [address] = validator;
if (chain.valset_data.length == 0 || chain.valset_data[0].indexOf(address) == -1) {
chain.valset_data[0].push(address);
let len = chain.valset_data.length;
for (let i = 1; i < len; i++) {
chain.valset_data[i].push(0);
}
}
});
let newRow = [set.height, set.sha256hash, set.total_vp];
let len = chain.valset_data[0].length;
for (let i = 3; i < len; i++) {
Object.entries(set.validators).forEach(validator => {
const [address, voting_power] = validator;
if (chain.valset_data[0][i] == address) {
newRow[i] = parseFloat(voting_power);
}
else {
if (Object.keys(set.validators).indexOf(chain.valset_data[0][i]) == -1) {
newRow[i] = 0;
}
}
});
}
chain.valset_data.push(newRow);
console.log('> new set: ' + chain.id + ' | height: ' + set.height + ' | valset_hash: ' + set.sha256hash);
return;
}
function completeSet(valset, height) {
let valset_export = [];
let total_vp = 0;
let complete_set = {
"validators": {}
};
valset.forEach((validator) => {
valset_export.push(validator.address, validator.voting_power);
complete_set.validators[validator.address] = validator.voting_power;
total_vp = total_vp + parseFloat(validator.voting_power);
});
complete_set.total_vp = total_vp;
complete_set.height = height;
complete_set.sha256hash = hash(valset_export.toString());
return complete_set;
}
// fetch new valset
async function fetchNewValset(chain) {
let res = await fetchLatestValset(chain);
let height = res.block_height;
if (height > chain.last_height) {
console.log(chain.id + ' block: ' + res.block_height)
let valset = res.validators;
let complete_set = completeSet(valset, height);
chain.last_height = height;
return complete_set;
}
return false;
}
async function alertAndDumpSet(cc_new_set) {
// alert log
console.log('> DIFFERING VALSETS DETECTED!')
console.log('PC height: ' + provider.last_height);
console.log('CC height: ' + cc_new_set.height);
console.log('CC set ' + cc_new_set.sha256hash + ' not found in historic valsets of ' + provider.id + ' !')
console.log('CC dumping ' + consumer.id + ' set');
console.log(JSON.stringify(cc_new_set.valset));
// save valset to disk
dumpValsetRecords;
return true;
}
// poll lcd every 1s and check for new blocks/valsets
async function compareLiveValsets() {
let pc_new_set = await fetchNewValset(provider);
let cc_new_set = await fetchNewValset(consumer);
if (pc_new_set) {
if (isUniqueHash(provider, pc_new_set.sha256hash)) {
appendSet(provider, pc_new_set);
}
}
if (cc_new_set) {
if (isUniqueHash(consumer, cc_new_set.sha256hash)) {
appendSet(consumer, cc_new_set);
}
if (isUniqueHash(provider, cc_new_set.sha256hash)) {
alertAndDumpSet(cc_new_set);
}
}
return;
}
function isUniqueHash(chain, hash) {
let len = chain.valset_data.length;
let unique_hash = true;
for (var i = 0; i < len; i++) {
if (chain.valset_data[i][1] == hash) {
unique_hash = false;
}
}
return unique_hash;
}
// fetch historic valsets of PC
async function fetchHistoricValsets(chain) {
console.log("fetching historic valsets for chain " + chain.id + "...")
let block = chain.start_height;
let res = await fetchLatestValset(chain);
let last_block = res.block_height;
while (block <= last_block) {
if (block == last_block) {
res = await fetchLatestValset(chain);
if (res) {
last_block = res.block_height;
}
}
try {
res = await axios.get(chain.lcd + '/validatorsets/' + block);
}
catch (e) {
console.log(e.data);
return;
}
if (res) {
res = res.data.result;
let valset = res.validators;
let complete_set = completeSet(valset, block);
let unique_hash = isUniqueHash(chain, complete_set.sha256hash);
if (unique_hash == true) {
console.log('new set! height ' + block)
appendSet(chain, complete_set);
}
console.log("fetched " + chain.id + " block " + block);
// compare CC blocks
if (chain.id == consumer.id) {
let unique_hash = isUniqueHash(provider, complete_set.sha256hash);
if (unique_hash) {
await alertAndDumpSet(complete_set);
}
}
chain.last_height = block;
block++;
}
}
return;
}
async function main() {
// compare all historic valsets
await fetchHistoricValsets(provider);
await fetchHistoricValsets(consumer);
// save historic valset records to disk
dumpValsetRecords()
// compare live valsets
setInterval(compareLiveValsets, 1000);
compareLiveValsets();
return;
}
main();
**[EDIT 2022/11/16] code updated, differing valset theory below falsified with updated script! Gist depracted in favour of https://github.com/clemensgg/game-of-chains/**
###
PC: provider
CC: sputnik
> DIFFERING VALSETS DETECTED!
CC set 2665be94be5c98455ae6d196f4459f53b0722164e92121b13ecdb550278bb299 not found in last 100 blocks of PC!
PC height: 57206
CC height: 3785
dumping CONSUMER valset...
["cosmosvalcons1dg72e6h2tpkf4uc9zfyadle5js5rthcs892vnj","670100004","cosmosvalcons1pk34jc9vww287s2ef8k6lzz7r2dpscms7af6ny","784","cosmosvalcons1nyquekjzh9ywmhyrt76u32cxwv9fcg7dxprygj","427","cosmosvalcons172wrmvq0w0m4mp9hmlw80pal0z53c65punhf2k","310","cosmosvalcons15w5mjufgd8ezfa83709nmews88tzdrepugw2jd","300","cosmosvalcons1kke43d43wpfw9cdqpw8d0qf8ll0ltp90a4jpja","93","cosmosvalcons1e5x6sh63qdz74m9h8thddc7zceddyljnhkcdsu","39","cosmosvalcons1dkw3fgnjnwjlq2hjqw46l4wws2zd6fns063eyq","31","cosmosvalcons1z5q6n9hd24mlcew407f2ej8ptnnt0haddknugk","26","cosmosvalcons1lj2q9l6t2wutwf3yclaj3h0yj7t7736t09d42h","25","cosmosvalcons1yna32lcuhtjkq7f4nsnp9ln8wykwjepxhxsr5g","23","cosmosvalcons123zrau6pyk7mma6d3c0armpc2utqau7vm88u9x","19","cosmosvalcons1zq7v8lz7jrqyacsgh5r3dhygj4ffymhckysvw6","18","cosmosvalcons1ual79gxh0p8eeet46d0sn7an8wc9ej0t2hav6n","18","cosmosvalcons16hf7ktj7yds8sta04d7qk0z9hla3tpatsd0vf5","17","cosmosvalcons1lx9nq9909u49ezzjyc7ktg9k08ahnxuvhsj2ym","17","cosmosvalcons18wv3ddgpc5lrsq2kwc5z798z4tcztak9yny2x5","16","cosmosvalcons13feufd67xc8lrydcgjnphzz95zkkt5sgwkzccn","16","cosmosvalcons12freezz7w0f02ux50e0sgvmc2pgn2rw3pukgsc","15","cosmosvalcons1jh3lz46dmdgr7quqmx9fwmsvlprfhp60x8aaer","11","cosmosvalcons1qqlx7730mz96503pz729vu07pkv5u9ca85dhwe","10","cosmosvalcons1qwzmrx23fayrsudhhqq6jgal2wthk2gklq43vd","10","cosmosvalcons1q04tlwzqn38k9fej50tj3t929cf5q06s37z0y8","10","cosmosvalcons1q4ht5pn0kc64le4crl0nwhqumh6maw7x37696r","10","cosmosvalcons1pw8cra4g934nwzxkrykz45d4xgy7qnmvvtuaqt","10","cosmosvalcons1ze39xyf4t3ye8ldxn5scsaw2adur7ek4tt5jmp","10","cosmosvalcons1rljsrflyeuzf3we6kghkf4qjeqflsygepnzl53","10","cosmosvalcons1y022gjzdfkrggfekjzyvf59zu4k64ar98aau5k","10","cosmosvalcons19y4nwy0ygg7z73ahhevt7uh090g8wr8sgv6n2l","10","cosmosvalcons1xpgp8n9xnpnd49pzv4jf6444048j23wvtsnvak","10","cosmosvalcons1xhfftsd6wxx6jxl7xsdv8hsfk7txjgwf73uq6q","10","cosmosvalcons1xc0aszah3y7yksgy6rt63jf37d3dzuxcr8s59x","10","cosmosvalcons184pytrwcz8yjrndz5zq0kqvvhw3tj88a90hv5m","10","cosmosvalcons1gx49m7vtmw9gpxu4dfujtnepl2g96zxasea2j9","10","cosmosvalcons1g2ysa6n7nvpgjps9zdf4dkgtvse6ga6f6kmepz","10","cosmosvalcons1g4zw77yzsh34sfkm9rkx9ltsg42vcu2kgt95gy","10","cosmosvalcons1f4hpdclhmz0gmqulw95f844plqwfl9td6qcqym","10","cosmosvalcons12t4pcfx6jnr84rld03rwrzsul3rk64che77jfz","10","cosmosvalcons12h4v7ms5wfhp87tnjqmpgzrcvaqymuk2v49c7q","10","cosmosvalcons12lfvpusgm69kq0dxexm4ek2uxfvhhc6grdxfa8","10","cosmosvalcons1t8xflpfzx4rnmatmemehcc8n52wmx6q3g4mxch","10","cosmosvalcons1tg3gv86h7y5znd52qghmsptgtf89s5xre3edlr","10","cosmosvalcons1t0kswnadw2e5rh3xksmz3uh7pyt6c8trcfwe5k","10","cosmosvalcons1thhlg48txpsclg4e0rvl78yt2ge3ruw3utwd7q","10","cosmosvalcons1vr0ajahfkaytrc0sdltmdqy6xu9a8gcz76c48z","10","cosmosvalcons1v5v9hsn4awfr9gkl7ga7kn42qada457w83pqdz","10","cosmosvalcons1v6zrud945rxq6nl6eexf9rfqqafafwwnx57rvy","10","cosmosvalcons1vuwq3w64c8py9hz6xs5gnnvvqpccj0lesm3u0k","10","cosmosvalcons1w86lpg205h9gsy32yetfkrp6nc7xuh90dz5uy3","10","cosmosvalcons1wns96l4057a75jez52hlhvw2d7t5wze4ke90cz","10","cosmosvalcons1wmvevar5kc5rtecr54m3q8gl6d0cf5mt29jcy9","10","cosmosvalcons108aypezdajecj03kg66c4gfu0l5f3053x392lf","10","cosmosvalcons10f4xx96k72eypj7l4qwlv4x6hfvecrenl09tsx","10","cosmosvalcons10f6wkg5ckfkvnucvr35z5hqdugy7ud58rfsxmn","10","cosmosvalcons10vx7jlqg9tnezxfgqp873v294g0l2cpchuw6qc","10","cosmosvalcons10crq9qa7gp8paqxwwwxae3kp970duqgn0s9qcc","10","cosmosvalcons10m4u3cyxmdj98ame2nzye9xkldhs5cj7jm6yq5","10","cosmosvalcons1s7kc8tyvsj47tkyfpexlusrlz77dg26wmvt0hx","10","cosmosvalcons1sl5j5snqwqts3ru9qc0zqunmu08lvxvekpj2mt","10","cosmosvalcons133lxdszpdgqzel834x0c3uelej84nx2yhrey5d","10","cosmosvalcons13aa4rs0g2g8qh75ffmvryylyth43pc2kgmgdpf","10","cosmosvalcons1j6yyhc5af53347us6q68fq5x65dxh62rym9aq5","10","cosmosvalcons1jur4mxvvz9m3kw925zk0hl0snmks0z7fwmlc9x","10","cosmosvalcons1j7t42uegq7dm85l93rddsulsafkqnrqsnjtf5s","10","cosmosvalcons1nqz3a6w3zxpx6zsrh0wsxdx8cfr0c33k38lk8e","10","cosmosvalcons1nd2fpxeephw7tmqpgymrq3gvjpzwlr3wvjttu6","10","cosmosvalcons1njrm0dasu7d5h6qawtrtdrm3y27tqnhv0vxdyc","10","cosmosvalcons15xu5spj4r5j63wwyk4gwhmq7nvvkzx348krpn6","10","cosmosvalcons15t3h8hqgjj7qe584c75weu30r70g74tep3yuta","10","cosmosvalcons14fm6gslcf9sx5j5wk93ew5sx3sdza6j7vr96r4","10","cosmosvalcons14knt8vk78wexsmd7792rcvyazrfraskv6hpm2t","10","cosmosvalcons1k3m4krltmlsz84hzgaytm59nn7pkd2xaygdpj0","10","cosmosvalcons1kkdkxvcl6gfqezdl9e7av4l8lx4qjzsaj380nf","10","cosmosvalcons1ht8qrurx6lpngj4pjns6rdhm7mlga0suun8jwk","10","cosmosvalcons1hexe6e6hnk0fan7n9vu6kt40nz86022kmyg9qp","10","cosmosvalcons1cq35fan5z5r5csl2rddjqclun93jn3hpxh2v0g","10","cosmosvalcons1csa5vmvu8fsgtxmx5j8qk4xxv278q8a4pce87v","10","cosmosvalcons1cave3x44qrklv2wyemgjvl9rpanquspyeqvk4m","10","cosmosvalcons1eszcs2tcl30a66nhy958u9xq9xdwqp9c65dnm6","10","cosmosvalcons1ek3cslf0ppj7sjavnjpyr494luu4j8fgdf6n8d","10","cosmosvalcons16q4jna57d07rufql8qtzaqhwf3ud3hdf5yt3y2","10","cosmosvalcons16p3evw80wdns6jqna8grfazfjenm80n7cle8kj","10","cosmosvalcons1635xssr82smqqr5mxwu2tqvnh9qx4hdresz7fw","10","cosmosvalcons16etd37wqd3h3209pwf7w86ast0c4vapcvf349n","10","cosmosvalcons1m9zg6xjs0g8hjtp97nl2uqwah3r53j5z6a9ppw","10","cosmosvalcons1md008gt5q9z3tgzxaq8rze8zys2pyds596lfv6","10","cosmosvalcons1msqd5pywcs9l99fsvfnqrpqtrr6g4j99uqmckk","10","cosmosvalcons1uykcdtp8jfvuhvxvr5k9m206mcla35j09s3q49","10","cosmosvalcons1uxjga5twkestune9nc8r5c4chet0g83kdf7u68","10","cosmosvalcons1uc6e0cl5duageq3hnfedxl7h62qwsvh6ppkgc4","10","cosmosvalcons1aegqgn27upl69skvjnc6s8ftdkkuzqlt46r6tg","10","cosmosvalcons17m4ucgq6q5wzzp4x7rxetfzjeppm5nc5f9nc32","10","cosmosvalcons1lhnmnmd9arv33wsyyd06xp928n5zcpxp4t8k0t","10","cosmosvalcons1y9r49naje4wtqrkxy4eecgj25srzymgw8k5ywt","9","cosmosvalcons1efueez5q0x6m4sruhnmhe9x2q5xtfjuqazpjhc","5"]
dumping last PROVIDER valset...
["cosmosvalcons1dg72e6h2tpkf4uc9zfyadle5js5rthcs892vnj","670100004","cosmosvalcons1pk34jc9vww287s2ef8k6lzz7r2dpscms7af6ny","784","cosmosvalcons1nyquekjzh9ywmhyrt76u32cxwv9fcg7dxprygj","427","cosmosvalcons172wrmvq0w0m4mp9hmlw80pal0z53c65punhf2k","310","cosmosvalcons15w5mjufgd8ezfa83709nmews88tzdrepugw2jd","300","cosmosvalcons1kke43d43wpfw9cdqpw8d0qf8ll0ltp90a4jpja","93","cosmosvalcons1e5x6sh63qdz74m9h8thddc7zceddyljnhkcdsu","39","cosmosvalcons1dkw3fgnjnwjlq2hjqw46l4wws2zd6fns063eyq","31","cosmosvalcons1z5q6n9hd24mlcew407f2ej8ptnnt0haddknugk","26","cosmosvalcons1lj2q9l6t2wutwf3yclaj3h0yj7t7736t09d42h","25","cosmosvalcons1yna32lcuhtjkq7f4nsnp9ln8wykwjepxhxsr5g","23","cosmosvalcons123zrau6pyk7mma6d3c0armpc2utqau7vm88u9x","19","cosmosvalcons1zq7v8lz7jrqyacsgh5r3dhygj4ffymhckysvw6","18","cosmosvalcons1ual79gxh0p8eeet46d0sn7an8wc9ej0t2hav6n","18","cosmosvalcons16hf7ktj7yds8sta04d7qk0z9hla3tpatsd0vf5","17","cosmosvalcons1lx9nq9909u49ezzjyc7ktg9k08ahnxuvhsj2ym","17","cosmosvalcons18wv3ddgpc5lrsq2kwc5z798z4tcztak9yny2x5","16","cosmosvalcons13feufd67xc8lrydcgjnphzz95zkkt5sgwkzccn","16","cosmosvalcons12freezz7w0f02ux50e0sgvmc2pgn2rw3pukgsc","15","cosmosvalcons1jh3lz46dmdgr7quqmx9fwmsvlprfhp60x8aaer","11","cosmosvalcons1qqlx7730mz96503pz729vu07pkv5u9ca85dhwe","10","cosmosvalcons1qwzmrx23fayrsudhhqq6jgal2wthk2gklq43vd","10","cosmosvalcons1q04tlwzqn38k9fej50tj3t929cf5q06s37z0y8","10","cosmosvalcons1q4ht5pn0kc64le4crl0nwhqumh6maw7x37696r","10","cosmosvalcons1pw8cra4g934nwzxkrykz45d4xgy7qnmvvtuaqt","10","cosmosvalcons1ze39xyf4t3ye8ldxn5scsaw2adur7ek4tt5jmp","10","cosmosvalcons1rljsrflyeuzf3we6kghkf4qjeqflsygepnzl53","10","cosmosvalcons1y022gjzdfkrggfekjzyvf59zu4k64ar98aau5k","10","cosmosvalcons19y4nwy0ygg7z73ahhevt7uh090g8wr8sgv6n2l","10","cosmosvalcons1xpgp8n9xnpnd49pzv4jf6444048j23wvtsnvak","10","cosmosvalcons1xhfftsd6wxx6jxl7xsdv8hsfk7txjgwf73uq6q","10","cosmosvalcons1xc0aszah3y7yksgy6rt63jf37d3dzuxcr8s59x","10","cosmosvalcons184pytrwcz8yjrndz5zq0kqvvhw3tj88a90hv5m","10","cosmosvalcons1gx49m7vtmw9gpxu4dfujtnepl2g96zxasea2j9","10","cosmosvalcons1g2ysa6n7nvpgjps9zdf4dkgtvse6ga6f6kmepz","10","cosmosvalcons1g4zw77yzsh34sfkm9rkx9ltsg42vcu2kgt95gy","10","cosmosvalcons1f4hpdclhmz0gmqulw95f844plqwfl9td6qcqym","10","cosmosvalcons12t4pcfx6jnr84rld03rwrzsul3rk64che77jfz","10","cosmosvalcons12h4v7ms5wfhp87tnjqmpgzrcvaqymuk2v49c7q","10","cosmosvalcons12lfvpusgm69kq0dxexm4ek2uxfvhhc6grdxfa8","10","cosmosvalcons1t8xflpfzx4rnmatmemehcc8n52wmx6q3g4mxch","10","cosmosvalcons1tg3gv86h7y5znd52qghmsptgtf89s5xre3edlr","10","cosmosvalcons1t0kswnadw2e5rh3xksmz3uh7pyt6c8trcfwe5k","10","cosmosvalcons1thhlg48txpsclg4e0rvl78yt2ge3ruw3utwd7q","10","cosmosvalcons1vr0ajahfkaytrc0sdltmdqy6xu9a8gcz76c48z","10","cosmosvalcons1v5v9hsn4awfr9gkl7ga7kn42qada457w83pqdz","10","cosmosvalcons1v6zrud945rxq6nl6eexf9rfqqafafwwnx57rvy","10","cosmosvalcons1vuwq3w64c8py9hz6xs5gnnvvqpccj0lesm3u0k","10","cosmosvalcons1w86lpg205h9gsy32yetfkrp6nc7xuh90dz5uy3","10","cosmosvalcons1wns96l4057a75jez52hlhvw2d7t5wze4ke90cz","10","cosmosvalcons1wmvevar5kc5rtecr54m3q8gl6d0cf5mt29jcy9","10","cosmosvalcons108aypezdajecj03kg66c4gfu0l5f3053x392lf","10","cosmosvalcons10f4xx96k72eypj7l4qwlv4x6hfvecrenl09tsx","10","cosmosvalcons10f6wkg5ckfkvnucvr35z5hqdugy7ud58rfsxmn","10","cosmosvalcons10vx7jlqg9tnezxfgqp873v294g0l2cpchuw6qc","10","cosmosvalcons10crq9qa7gp8paqxwwwxae3kp970duqgn0s9qcc","10","cosmosvalcons10m4u3cyxmdj98ame2nzye9xkldhs5cj7jm6yq5","10","cosmosvalcons1s7kc8tyvsj47tkyfpexlusrlz77dg26wmvt0hx","10","cosmosvalcons1sl5j5snqwqts3ru9qc0zqunmu08lvxvekpj2mt","10","cosmosvalcons133lxdszpdgqzel834x0c3uelej84nx2yhrey5d","10","cosmosvalcons13aa4rs0g2g8qh75ffmvryylyth43pc2kgmgdpf","10","cosmosvalcons1j6yyhc5af53347us6q68fq5x65dxh62rym9aq5","10","cosmosvalcons1jur4mxvvz9m3kw925zk0hl0snmks0z7fwmlc9x","10","cosmosvalcons1j7t42uegq7dm85l93rddsulsafkqnrqsnjtf5s","10","cosmosvalcons1nqz3a6w3zxpx6zsrh0wsxdx8cfr0c33k38lk8e","10","cosmosvalcons1nd2fpxeephw7tmqpgymrq3gvjpzwlr3wvjttu6","10","cosmosvalcons1njrm0dasu7d5h6qawtrtdrm3y27tqnhv0vxdyc","10","cosmosvalcons15xu5spj4r5j63wwyk4gwhmq7nvvkzx348krpn6","10","cosmosvalcons15t3h8hqgjj7qe584c75weu30r70g74tep3yuta","10","cosmosvalcons14fm6gslcf9sx5j5wk93ew5sx3sdza6j7vr96r4","10","cosmosvalcons14knt8vk78wexsmd7792rcvyazrfraskv6hpm2t","10","cosmosvalcons1k3m4krltmlsz84hzgaytm59nn7pkd2xaygdpj0","10","cosmosvalcons1kkdkxvcl6gfqezdl9e7av4l8lx4qjzsaj380nf","10","cosmosvalcons1ht8qrurx6lpngj4pjns6rdhm7mlga0suun8jwk","10","cosmosvalcons1hexe6e6hnk0fan7n9vu6kt40nz86022kmyg9qp","10","cosmosvalcons1cq35fan5z5r5csl2rddjqclun93jn3hpxh2v0g","10","cosmosvalcons1csa5vmvu8fsgtxmx5j8qk4xxv278q8a4pce87v","10","cosmosvalcons1cave3x44qrklv2wyemgjvl9rpanquspyeqvk4m","10","cosmosvalcons1efueez5q0x6m4sruhnmhe9x2q5xtfjuqazpjhc","10","cosmosvalcons1eszcs2tcl30a66nhy958u9xq9xdwqp9c65dnm6","10","cosmosvalcons1ek3cslf0ppj7sjavnjpyr494luu4j8fgdf6n8d","10","cosmosvalcons16q4jna57d07rufql8qtzaqhwf3ud3hdf5yt3y2","10","cosmosvalcons16p3evw80wdns6jqna8grfazfjenm80n7cle8kj","10","cosmosvalcons1635xssr82smqqr5mxwu2tqvnh9qx4hdresz7fw","10","cosmosvalcons16etd37wqd3h3209pwf7w86ast0c4vapcvf349n","10","cosmosvalcons1m9zg6xjs0g8hjtp97nl2uqwah3r53j5z6a9ppw","10","cosmosvalcons1md008gt5q9z3tgzxaq8rze8zys2pyds596lfv6","10","cosmosvalcons1msqd5pywcs9l99fsvfnqrpqtrr6g4j99uqmckk","10","cosmosvalcons1uykcdtp8jfvuhvxvr5k9m206mcla35j09s3q49","10","cosmosvalcons1uxjga5twkestune9nc8r5c4chet0g83kdf7u68","10","cosmosvalcons1uc6e0cl5duageq3hnfedxl7h62qwsvh6ppkgc4","10","cosmosvalcons1aegqgn27upl69skvjnc6s8ftdkkuzqlt46r6tg","10","cosmosvalcons17m4ucgq6q5wzzp4x7rxetfzjeppm5nc5f9nc32","10","cosmosvalcons1lhnmnmd9arv33wsyyd06xp928n5zcpxp4t8k0t","10","cosmosvalcons1y9r49naje4wtqrkxy4eecgj25srzymgw8k5ywt","9"]
###
@clemensgg
Copy link
Author

Gist depcrated in favor of https://github.com/clemensgg/game-of-chains

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment