Skip to content

Instantly share code, notes, and snippets.

@placecodex
Created November 14, 2020 21:33
Show Gist options
  • Save placecodex/c20124191eeb7461bc6e2f009c1708ce to your computer and use it in GitHub Desktop.
Save placecodex/c20124191eeb7461bc6e2f009c1708ce to your computer and use it in GitHub Desktop.
ethereum token transaction
// Dotenv javascript libraries needed
require('dotenv').config();
// Ethereum javascript libraries needed
var Web3 = require('web3');
var Tx = require('ethereumjs-tx');
// Rather than using a local copy of geth, interact with the ethereum blockchain via infura.io
// The key for infura.io is in .env
const web3 = new Web3(Web3.givenProvider || "https://ropsten.infura.io/" + process.env["INFURA_KEY"])
// Fixed-point notation for number of MFIL which is divisible to 3 decimal places
function financialMfil(numMfil) {
return Number.parseFloat(numMfil / 1e3).toFixed(3);
}
// Create an async function so I can use the "await" keyword to wait for things to finish
const main = async () => {
// This code was written and tested using web3 version 1.0.0-beta.29
console.log(`web3 version: ${web3.version}`)
// Who holds the token now?
var myAddress = "0x644dE7C3f6425D8920332FC6C97Fbf7e04445C74";
// Who are we trying to send this token to?
var destAddress = "0xE3A029F6cA0C32a9E6c9a2154790Ea0A92cb2621";
// MineFIL Token (MFIL) is divisible to 3 decimal places, 1 = 0.001 of MFIL
var transferAmount = 1;
// Determine the nonce
var count = await web3.eth.getTransactionCount(myAddress);
console.log(`num transactions so far: ${count}`);
// MineFILToekn contract ABI Array
var abiArray = [{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [{
"name": "",
"type": "string"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"constant": false,
"inputs": [{
"name": "_spender",
"type": "address"
}, {
"name": "_value",
"type": "uint256"
}],
"name": "approve",
"outputs": [{
"name": "",
"type": "bool"
}],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}, {
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [{
"name": "",
"type": "uint256"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"constant": false,
"inputs": [{
"name": "_from",
"type": "address"
}, {
"name": "_to",
"type": "address"
}, {
"name": "_value",
"type": "uint256"
}],
"name": "transferFrom",
"outputs": [{
"name": "",
"type": "bool"
}],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}, {
"constant": true,
"inputs": [],
"name": "INITIAL_SUPPLY",
"outputs": [{
"name": "",
"type": "uint256"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [{
"name": "",
"type": "uint8"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"constant": false,
"inputs": [{
"name": "_spender",
"type": "address"
}, {
"name": "_subtractedValue",
"type": "uint256"
}],
"name": "decreaseApproval",
"outputs": [{
"name": "",
"type": "bool"
}],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}, {
"constant": true,
"inputs": [{
"name": "_owner",
"type": "address"
}],
"name": "balanceOf",
"outputs": [{
"name": "balance",
"type": "uint256"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [{
"name": "",
"type": "string"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"constant": false,
"inputs": [{
"name": "_to",
"type": "address"
}, {
"name": "_value",
"type": "uint256"
}],
"name": "transfer",
"outputs": [{
"name": "",
"type": "bool"
}],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}, {
"constant": false,
"inputs": [{
"name": "_spender",
"type": "address"
}, {
"name": "_addedValue",
"type": "uint256"
}],
"name": "increaseApproval",
"outputs": [{
"name": "",
"type": "bool"
}],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}, {
"constant": true,
"inputs": [{
"name": "_owner",
"type": "address"
}, {
"name": "_spender",
"type": "address"
}],
"name": "allowance",
"outputs": [{
"name": "",
"type": "uint256"
}],
"payable": false,
"stateMutability": "view",
"type": "function"
}, {
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
}, {
"anonymous": false,
"inputs": [{
"indexed": true,
"name": "owner",
"type": "address"
}, {
"indexed": true,
"name": "spender",
"type": "address"
}, {
"indexed": false,
"name": "value",
"type": "uint256"
}],
"name": "Approval",
"type": "event"
}, {
"anonymous": false,
"inputs": [{
"indexed": true,
"name": "from",
"type": "address"
}, {
"indexed": true,
"name": "to",
"type": "address"
}, {
"indexed": false,
"name": "value",
"type": "uint256"
}],
"name": "Transfer",
"type": "event"
}]
// The address of the contract which created MFIL
var contractAddress = "0x1564A92a0870aF0eBf1F015f5FD223abaA3505CA";
var contract = new web3.eth.Contract(abiArray, contractAddress, {
from: myAddress
});
// How many tokens do I have before sending?
var balance = await contract.methods.balanceOf(myAddress).call();
console.log(`Balance before send: ${financialMfil(balance)} MFIL\n------------------------`);
// I chose gas price and gas limit based on what ethereum wallet was recommending for a similar transaction. You may need to change the gas price!
// Use Gwei for the unit of gas price
var gasPriceGwei = 3;
var gasLimit = 3000000;
// Chain ID of Ropsten Test Net is 3, replace it to 1 for Main Net
var chainId = 3;
var rawTransaction = {
"from": myAddress,
"nonce": "0x" + count.toString(16),
"gasPrice": web3.utils.toHex(gasPriceGwei * 1e9),
"gasLimit": web3.utils.toHex(gasLimit),
"to": contractAddress,
"value": "0x0",
"data": contract.methods.transfer(destAddress, transferAmount).encodeABI(),
"chainId": chainId
};
console.log(`Raw of Transaction: \n${JSON.stringify(rawTransaction, null, '\t')}\n------------------------`);
// The private key for myAddress in .env
var privKey = new Buffer(process.env["PRIVATE_KEY"], 'hex');
var tx = new Tx(rawTransaction);
tx.sign(privKey);
var serializedTx = tx.serialize();
// Comment out these four lines if you don't really want to send the TX right now
console.log(`Attempting to send signed tx: ${serializedTx.toString('hex')}\n------------------------`);
var receipt = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'));
// The receipt info of transaction, Uncomment for debug
console.log(`Receipt info: \n${JSON.stringify(receipt, null, '\t')}\n------------------------`);
// The balance may not be updated yet, but let's check
balance = await contract.methods.balanceOf(myAddress).call();
console.log(`Balance after send: ${financialMfil(balance)} MFIL`);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment