-
-
Save gamalielhere/0ed7aeaef9e8e8c17fed9dd6d3db2b62 to your computer and use it in GitHub Desktop.
Figures out what tokens are missing from the MEW token contract
This file contains hidden or 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
GET_TOKEN_DEFAULT_PARAM='' // Data object for getAllBAlance for the contract | |
CONTRACT_ADDRESS='' // Contract address | |
TOKEN_LIST_SRC='' // Token list source | |
PRIV='' // account private key | |
RPC='' // Node you're connecting to | |
GAS_PRICE = 0 | |
GAS = 0 |
This file contains hidden or 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
require("dotenv").config(); | |
const fs = require("fs"); | |
const Web3 = require("web3"); | |
const fetch = require("node-fetch"); | |
const BigNumber = require("bignumber.js"); | |
const abi = require("./contractABI.js"); | |
const ethUtil = require("ethereumjs-util"); | |
const ethTx = require("ethereumjs-tx"); | |
const privateKey = Buffer.from(process.env.PRIV, 'hex'); | |
let web3 = new Web3(); | |
web3.setProvider(new web3.providers.HttpProvider(process.env.RPC)); | |
function getDataString(func, inputs) { | |
return web3.eth.abi.encodeFunctionCall(func, inputs); | |
} | |
function sizeHex(bytes) { | |
return bytes * 2; | |
} | |
function sortAlphabetically(a, b) { | |
const first = a.symbol.toUpperCase(); | |
const second = b.symbol.toUpperCase(); | |
return first < second ? -1 : first > second ? 1 : 0; | |
} | |
function trim(str) { | |
return str.replace(/\0[\s\S]*$/g, ""); | |
} | |
function getAscii(hex) { | |
hex = hex.substring(0, 2) === "0x" ? hex : "0x" + hex; | |
return trim(web3.utils.hexToAscii(hex)); | |
} | |
function parseContractToken(hex) { | |
let tokens = []; | |
hex = hex.substring(0, 2) === "0x" ? hex.substring(2) : hex; | |
hex = hex.substring(0, hex.lastIndexOf("1") - 1); //starting point | |
let offset = hex.length; | |
offset -= sizeHex(32); | |
let countTokens = hex.substr(offset, sizeHex(32)); | |
offset -= sizeHex(1); | |
let isName = parseInt(hex.substr(offset, sizeHex(1))); | |
offset -= sizeHex(1); | |
let isWebSite = parseInt(hex.substr(offset, sizeHex(1))); | |
offset -= sizeHex(1); | |
let isEmail = parseInt(hex.substr(offset, sizeHex(1))); | |
let numTokens = new BigNumber("0x" + countTokens).toNumber(); | |
for (var i = 0; i < parseInt(numTokens); i++) { | |
var token = {}; | |
offset -= sizeHex(16); | |
token.symbol = getAscii(hex.substr(offset, sizeHex(16))); | |
offset -= sizeHex(20); | |
token.addr = "0x" + hex.substr(offset, sizeHex(20)); | |
offset -= sizeHex(8); | |
token.decimals = new BigNumber( | |
"0x" + hex.substr(offset, sizeHex(8)) | |
).toNumber(); | |
offset -= sizeHex(32); | |
token.balance = new BigNumber( | |
"0x" + hex.substr(offset, sizeHex(32)) | |
).toFixed(); | |
if (isName) { | |
offset -= sizeHex(16); | |
token.name = getAscii(hex.substr(offset, sizeHex(16))); | |
} | |
if (isWebSite) { | |
offset -= sizeHex(32); | |
token.website = getAscii(hex.substr(offset, sizeHex(32))); | |
} | |
if (isEmail) { | |
offset -= sizeHex(32); | |
token.email = getAscii(hex.substr(offset, sizeHex(32))); | |
} | |
tokens.push(token); | |
} | |
return tokens; | |
} | |
async function getMEWTokens() { | |
const response = await fetch(process.env.TOKEN_LIST_SRC); | |
const mewTokens = await response.json(); | |
return mewTokens; | |
} | |
async function getContractTokens() { | |
const newTokens = await web3.eth | |
.call({ | |
to: process.env.CONTRACT_ADDRESS, | |
data: process.env.GET_TOKEN_DEFAULT_PARAM | |
}) | |
.then(function(res) { | |
return parseContractToken(res); | |
}) | |
.catch(function(err) { | |
throw err; | |
}); | |
return newTokens; | |
} | |
var getHex = (str) => { | |
return '0x' + Buffer.from(str, 'utf8').toString('hex') | |
} | |
async function differenceTokenList(arr) { | |
if(arr.length > 0) { | |
this.tokensAbi = {}; | |
for (var i in abi) this.tokensAbi[abi[i].name] = abi[i]; | |
fs.writeFileSync('./notInContractTokens.json', JSON.stringify(arr)); | |
const FROM = | |
"0x" + ethUtil.privateToAddress("0x"+process.env.PRIV).toString("hex"); | |
for (let i = 0; i < arr.length; i++) { | |
let txCount = await web3.eth.getTransactionCount(FROM); | |
let name = getHex(arr[i].name); | |
let symbol = getHex(arr[i].symbol); | |
let address = arr[i].address; | |
let decimal = arr[i].decimals; | |
let website = getHex(arr[i].website); | |
let email = getHex(arr[i].support.email); | |
let dataStr = getDataString(this.tokensAbi.addSetToken, [name, symbol, address, decimal, website, email]); | |
const params = { | |
nonce: web3.utils.toHex(txCount + i), | |
gasPrice: web3.utils.toHex(process.env.GAS_PRICE), | |
gasLimit: web3.utils.toHex(process.env.GAS), | |
to: web3.utils.toHex(process.env.CONTRACT_ADDRESS), | |
value: '0x0', | |
data: dataStr, | |
chainId: 1 | |
} | |
const tx = new ethTx(params); | |
tx.sign(privateKey); | |
const serializedTx = tx.serialize(); | |
const actualTransactionParams = '0x' + serializedTx.toString('hex'); | |
new Promise(function(resolve, reject) { | |
web3.eth.sendSignedTransaction(actualTransactionParams).on('transactionHash',function(hash){ | |
console.log("Added token " + (arr[i].name, hash); | |
resolve(); | |
}).catch(function(err) { | |
console.log(err.message); | |
resolve(); | |
}) | |
}) | |
} | |
} | |
} | |
async function run() { | |
const mewTokens = await getMEWTokens(); | |
const contractTokens = await getContractTokens(); | |
let diffTokens = []; | |
mewTokens.forEach(function(mToken) { | |
if ( | |
!contractTokens.find(function(cToken) { | |
return ( | |
web3.utils.toChecksumAddress(cToken.addr) === | |
web3.utils.toChecksumAddress(mToken.address) | |
); | |
}) | |
) { | |
diffTokens.push(mToken); | |
} | |
}); | |
diffTokens.sort(sortAlphabetically); | |
differenceTokenList(diffTokens); | |
} | |
run(); |
This file contains hidden or 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
{ | |
"name": "token-contract", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1", | |
"start": "node index.js" | |
}, | |
"author": "", | |
"license": "ISC", | |
"devDependencies": { | |
"ethereumjs-tx": "^1.3.4", | |
"node-fetch": "^2.1.2", | |
"utf8": "^3.0.0", | |
"web3": "^1.0.0-beta.34" | |
}, | |
"dependencies": { | |
"bignumber.js": "^4.0.2", | |
"dotenv": "^5.0.1", | |
"ethereumjs-util": "^5.1.5" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment