Skip to content

Instantly share code, notes, and snippets.

@gamalielhere
Last active March 18, 2020 20:02
Show Gist options
  • Save gamalielhere/8f07af3cdd59bbbca070f767c9ab6faf to your computer and use it in GitHub Desktop.
Save gamalielhere/8f07af3cdd59bbbca070f767c9ab6faf to your computer and use it in GitHub Desktop.
Fetch tokens, filter out existing ones in the contract, create transactions to add missing ones
GET_TOKEN_DEFAULT_PARAM=0x80f4ae5c000000000000000000000000decaf9cd2367cdbb726e904cd6397edfcae6068d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000
CONTRACT_ADDRESS=0xBE1ecF8e340F13071761e0EeF054d9A511e1Cb56
TOKEN_LIST_SRC=https://raw.githubusercontent.com/MyEtherWallet/ethereum-lists/master/dist/tokens/eth/tokens-eth.min.json
PRIV=
RPC=https://api.myetherwallet.com/eth
GAS_PRICE = 5000000000
GAS = 300000
ACCOUNT_CONTRACT_ADDR = 0xDECAF9CD2367cdbb726E904cD6397eDFcAe6068D
module.exports = [
{
constant: true,
inputs: [
{
name: "",
type: "uint256"
}
],
name: "pubTokens",
outputs: [
{
name: "name",
type: "bytes16"
},
{
name: "symbol",
type: "bytes16"
},
{
name: "addr",
type: "address"
},
{
name: "decimals",
type: "uint8"
},
{
name: "website",
type: "bytes32"
},
{
name: "email",
type: "bytes32"
},
{
name: "isValid",
type: "bool"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "",
type: "address"
}
],
name: "idMap",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [],
name: "owner",
outputs: [
{
name: "",
type: "address"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [],
name: "tokenCount",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [],
name: "tokenValidCount",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "",
type: "address"
}
],
name: "moderator",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
inputs: [],
payable: false,
stateMutability: "nonpayable",
type: "constructor"
},
{
constant: false,
inputs: [
{
name: "addr",
type: "address"
}
],
name: "addModerator",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: false,
inputs: [
{
name: "addr",
type: "address"
}
],
name: "removeModerator",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: false,
inputs: [
{
name: "name",
type: "bytes16"
},
{
name: "symbol",
type: "bytes16"
},
{
name: "addr",
type: "address"
},
{
name: "decimals",
type: "uint8"
},
{
name: "website",
type: "bytes32"
},
{
name: "email",
type: "bytes32"
}
],
name: "addSetToken",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: false,
inputs: [
{
name: "addr",
type: "address"
}
],
name: "disableToken",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: false,
inputs: [
{
name: "addr",
type: "address"
}
],
name: "enableToken",
outputs: [],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: true,
inputs: [
{
name: "addr",
type: "address"
}
],
name: "getToken",
outputs: [
{
name: "",
type: "bytes16"
},
{
name: "",
type: "bytes16"
},
{
name: "",
type: "address"
},
{
name: "",
type: "uint8"
},
{
name: "",
type: "bytes32"
},
{
name: "",
type: "bytes32"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "id",
type: "uint256"
}
],
name: "getTokenById",
outputs: [
{
name: "",
type: "bytes16"
},
{
name: "",
type: "bytes16"
},
{
name: "",
type: "address"
},
{
name: "",
type: "uint8"
},
{
name: "",
type: "bytes32"
},
{
name: "",
type: "bytes32"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "_owner",
type: "address"
},
{
name: "name",
type: "bool"
},
{
name: "website",
type: "bool"
},
{
name: "email",
type: "bool"
},
{
name: "count",
type: "uint256"
}
],
name: "getAllBalance",
outputs: [
{
name: "",
type: "bytes"
}
],
payable: false,
stateMutability: "view",
type: "function"
}
];
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(process.env.RPC);
const TokenBalance = require('@myetherwallet/eth-token-balance').default;
const tb = new TokenBalance(web3.currentProvider);
function sortAlphabetically(a, b) {
const first = a.symbol.toUpperCase();
const second = b.symbol.toUpperCase();
return first < second ? -1 : first > second ? 1 : 0;
}
async function getMEWTokens() {
const response = await fetch(process.env.TOKEN_LIST_SRC);
const mewTokens = await response.json();
return mewTokens;
}
async function getContractTokens() {
const tokens = await tb.getBalance(process.env.ACCOUNT_CONTRACT_ADDR);
return tokens;
}
async function differenceTokenList(arr) {;
fs.writeFileSync("./notInContractTokens.json", JSON.stringify(arr));
if(arr.length > 0) {
const contract = new web3.eth.Contract(abi, process.env.CONTRACT_ADDRESS);
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 = arr[i].name.length > 7 ? web3.utils.utf8ToHex(arr[i].symbol) : web3.utils.utf8ToHex(arr[i].name);
let symbol = web3.utils.utf8ToHex(arr[i].symbol);
let address = web3.utils.toChecksumAddress(arr[i].address.toLowerCase());
let decimal = arr[i].decimals;
let website = web3.utils.asciiToHex(arr[i].website, 32).length > 64 ? '0x': web3.utils.asciiToHex(arr[i].website, 32);
let email = web3.utils.asciiToHex(arr[i].support.email, 32).length > 64 ? '0x': web3.utils.asciiToHex(arr[i].email, 32);
let dataStr = contract.methods.addSetToken(name, symbol, address, decimal, website, email).encodeABI();
// console.log(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');
web3.eth.sendSignedTransaction(actualTransactionParams).on('transactionHash', (hash) => {
console.log(`Added token ${arr[i].symbol} ${hash}"`);
}).on('error', e => {
console.log(e);
});
}
}
}
async function run() {
const mewTokens = await getMEWTokens();
const contractTokens = await getContractTokens();
let diffTokens = [];
mewTokens.forEach(mewTokes => {
const foundToken = contractTokens.find(conTokes => {
return web3.utils.toChecksumAddress(conTokes.addr.toLowerCase()) === web3.utils.toChecksumAddress(mewTokes.address.toLowerCase())
});
if (foundToken === undefined) {
diffTokens.push(mewTokes);
}
})
diffTokens.sort(sortAlphabetically);
differenceTokenList(diffTokens);
fs.writeFileSync("./contractTokens.json", JSON.stringify(contractTokens));
fs.writeFileSync("./mewTokens.json", JSON.stringify(mewTokens));
}
run();
{
"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": {
"@myetherwallet/eth-token-balance": "^0.1.3",
"ethereumjs-tx": "^1.3.4",
"node-fetch": "^2.1.2",
"utf8": "^3.0.0",
"web3": "^1.0.0-beta.37"
},
"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