Created
November 14, 2020 21:33
-
-
Save placecodex/c20124191eeb7461bc6e2f009c1708ce to your computer and use it in GitHub Desktop.
ethereum token transaction
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
// 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