Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transferring ERC20 tokens from account using web3 over Ropsten #1151

Closed
greggmojica opened this issue Oct 29, 2017 · 36 comments
Closed

Transferring ERC20 tokens from account using web3 over Ropsten #1151

greggmojica opened this issue Oct 29, 2017 · 36 comments

Comments

@greggmojica
Copy link

greggmojica commented Oct 29, 2017

I created a contract token using the sample solidity code tutorial. It has a function called transfer to send tokens between accounts:

function transfer(address _to, uint256 _value)

I need to now connect to this contract using web3, and then send a certain number of tokens generated to another account. I've been struggling with how to do this for quite some time and hoping this community could help. Here is what I have thus far, using web3 version 0.20.0:

```const Web3 = require("web3");
const web3 = new Web3();
web3.setProvider(new 
web3.providers.HttpProvider("https://ropsten.infura.io/XXXXXX"));
var abi = [ {} ] // redacted on purpose
var count = web3.eth.getTransactionCount("0x9...");
var abiArray = abi;
var contractAddress = "0x2...";
var contract =  web3.eth.contract(abiArray).at(contractAddress);

var data = contract.transfer.getData("0x2...", 10000, {from: "0x9..."});
var gasPrice = web3.eth.gasPrice;
var gasLimit = 90000;

var rawTransaction = {
  "from": "0x9...",
  "nonce": web3.toHex(count),
  "gasPrice": web3.toHex(gasPrice),
  "gasLimit": web3.toHex(gasLimit),
  "to": "0x2...",
  "value": "0x1",
  "data": data,
  "chainId": 0x03
};

var privKey = new Buffer('XXXXXXXXXXXXXX', 'hex');
var tx = new Tx(rawTransaction);

tx.sign(privKey);
var serializedTx = tx.serialize();

web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
  if (!err)
      console.log(hash);
  else
      console.log(err);
});```

This transaction works but it's sending ether as opposed to the actual ERC20 token. I'm really at a loss for why this is the case and would appreciate any help whatsoever.

@jdkanani
Copy link
Contributor

jdkanani commented Nov 2, 2017

Use following -

rawTransaction.from = "0x9..."; // as you have set in example
rawTransaction.value = 0; // as you don't want to send ether with transaction
rawTransaction.to = tokenAddress;
rawTransaction.data = contract.transfer.getData(userAddress, tokenValues); // user's address is the address you want to send tokens to.

@Nishchit14
Copy link

a new version of web3 1.x

 tx = {
  value: '0x0', 
  from: from,
  to: Contract._address,
  data: Contract.methods.transfer(to, 1000).encodeABI(),  
}

@sherhan361
Copy link

Hello! Give me, please, an example of the working code for sending tokens for the version of web3@1.0.0-beta.27. I'm trying to write code for these examples. But there are a lot of mistakes related to the irrelevance of the data. I think that it will be useful to many. Thank you!

@FradSer
Copy link

FradSer commented Jan 31, 2018

Single-address allocation of MineFIL Token (MFIL) code which was written and tested using web3 version 1.0.0-beta.29.

Check the MFIL Ethereum Smart Contract Scripts for more.

// 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();

@nickjuntilla
Copy link

@FradSer I get "SyntaxError: await is only valid in async function" when I run your code.

@nickjuntilla
Copy link

Not sure how people are using data: Contract.methods.transfer(to, 1000).encodeABI()

My web3 version is '0.20.4'

@nickjuntilla
Copy link

nickjuntilla commented Feb 13, 2018

So apparently FradSer through in async in there and then everything has changed to promises in the current web3, which may or may not be people have. To anyone else trying to figure out everything posted online is different try starting with this web3 version: "^1.0.0-beta.29"

@neohq
Copy link

neohq commented Feb 20, 2018

@nickjuntilla That piece of code you mentioned is from web3 1.0.0 (beta).

The code from @FradSer helped me finish mine, so big thanks!

@FradSer
Copy link

FradSer commented Feb 21, 2018

@nickjuntilla The code is written by 1.0.0-beta.29 , update your web3.

@ethan-deng
Copy link

ethan-deng commented Mar 1, 2018

The issue in the original question is that

var data = contract.transfer.getData("0x2...", 10000, {from: "0x9..."});

should be

var data = contract.transfer.getData("to_user_account_address_not_the_contract_address", 10000);

Use to user account address here but not the contract address. No need to use {from: "...} here.

Use the contract address in the raw transaction.

@sathyamlokare
Copy link

How do I deploy a contract by signing the transaction and unlocking the account using web3 ? Can anybody give a code snippet ? @FradSer please ?

@neohq
Copy link

neohq commented Mar 12, 2018

@sathyamlokare You don't need to unlock the account if you are signing the transaction using a privateKey. Here is a 100% functional code, if you have questions please ask.

PS:
args is a JSON that is sent from the front-end UI. It's just how I did it on my dev code.

        // Get args from front-end
        const args = JSON.parse(req.body.data)

        const gasPrice = await eth.getGasPrice()
        const gasPriceHex = web3.utils.toHex(gasPrice)
        const nonce = await eth.getTransactionCount( args['account'] )
        const nonceHex = web3.utils.toHex(nonce)

        const privateKey = new Buffer( args['privateKey'], 'hex')

        // JsonInterface data
        const jsonInterface = fs.readFileSync("json/contract-jsonInterface.json", 'utf8');

        // Contract byteCode
        const contractByteCode = fs.readFileSync("json/contract-bytecode.txt", 'utf8');

        // Create contract
        let contract = new eth.Contract(JSON.parse( jsonInterface ), null, {
            data: contractByteCode,
        } );

        // Init contract deploy
        let contractDeploy = await contract.deploy({
            arguments: [ args['initialSupply'], args['tokenName'], args['tokenSymbol'] ]
        })

        // Get estimated gas
        const estimatedGas = await contractDeploy.estimateGas();

        const rawTx = {
            nonce: nonceHex,
            gasPrice: gasPriceHex,
            gasLimit: web3.utils.toHex( estimatedGas + 10000 ),
            data: contractDeploy.encodeABI()
        }

        let tx = new Tx(rawTx)
        tx.sign(privateKey)

        const serializedTx = tx.serialize()

        // Send signed transaction
        let receipt = await eth.sendSignedTransaction( '0x' + serializedTx.toString('hex'))
            .on('error', function(error){
                console.log("-> error")
                console.log(error.message)
            })
            .on('transactionHash', function(transactionHash){
                console.log("-> transactionHash")
                console.log(transactionHash)
            })
            .on('receipt', function(receipt){
                console.log("-> receipt")
                console.log(receipt.contractAddress) // contains the new contract address
            })
            .on('confirmation', function(confirmationNumber, receipt){
                console.log("-> confirmation " + confirmationNumber)
            })

@sathyamlokare
Copy link

sathyamlokare commented Mar 13, 2018

@neohq can you help me with this , everything works fine here gets deployed. But it says TransactionReciept Status failed

var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("https://rinkeby.infura.io/022KbD1NPdb2YQ0Wi6vC"));

var Tx = require('ethereumjs-tx');
const testHashCoinAdvanced = require('./build/TokenERC20.json');

var privateKey = new Buffer('f6da78c45601d9ae02fcdb161e44a15a99e5e1fb1aa931dd95366add5dec367e', 'hex')


const deploy = async()=>{
 
           var contract = new web3.eth.Contract(JSON.parse(testHashCoinAdvanced[':TokenERC20'].interface));
          const hexdata = contract.deploy({
              data: '0x' + testHashCoinAdvanced[':TokenERC20'].bytecode,
              arguments:[1000,"HashCoin","HC"]
           }).encodeABI()

           const nonce = await web3.eth.getTransactionCount( "0x7Fb11F6A52e20BDFfaa08c468cD4848b901b7B70" );
           const nonceHex = web3.utils.toHex(nonce)
const gasPriceHex = web3.utils.toHex(3 * 1e9);
// const estimatedGas = await testCoinContractDeploy.estimateGas();
  var rawTx = {
      nonce: nonceHex,
      gasPrice: web3.utils.toHex(30000000000),
      gasLimit: web3.utils.toHex(6100500),
      data: "0x"+hexdata
  }

  var tx = new Tx(rawTx);
  tx.sign(privateKey);

  var serializedTx = tx.serialize();

  console.log(serializedTx.toString('hex')); 

  web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'))
      .on('receipt', console.log);

};
deploy();

you can check the transactions here
https://rinkeby.etherscan.io/address/0x7fb11f6a52e20bdffaa08c468cd4848b901b7b70

@jdkanani
Copy link
Contributor

@sathyamlokare Increase gas limit and try again.

@sathyamlokare
Copy link

@jdkanani I did that also, still getting the error

@neohq
Copy link

neohq commented Mar 13, 2018

@sathyamlokare If you are using Geth as a blockchain client, use 1.7.3 version, you are probably using the latest version 1.8.1 or 1.8.2 which has that problem you are describing.
You can take if from here https://ethereum.github.io/go-ethereum/downloads/

Using geth parameter --datadir you should point this version to another folder, to prevent overriding the default one .ethereum. Point 1.7.3 to .ethereum_1.7.3 for example.

@xntop
Copy link

xntop commented Mar 19, 2018

@neohq hello, i use your code, but has some errors when exec contract, this trans hash is https://rinkeby.etherscan.io/tx/0x77d854d47d65681e23f4780af45cb8cd7f935ee8a47a2249ac1fd7887cc21432 . and the code is
let options = { from: from, gasPrice: self.web3.utils.toHex(results.gasPrice), gas: self.web3.utils.toHex(800000) } const erc20Contract = new self.web3.eth.Contract(erc20Abi, '0x95Ed5d52531a743F3776C784a07746d9FbfCFc5e', options) var tx = new Tx({ from : from, to: erc20Contract._address, nonce: results.nonce, gasPrice: self.web3.utils.toHex(results.gasPrice), gasLimit: self.web3.utils.toHex(800000),//results.gasEstimate value: 0x0, data: erc20Contract.methods.transfer(to, amount).encodeABI() }); tx.sign(new Buffer(privateKey, 'hex')); self.web3.eth.sendSignedTransaction('0x' + tx.serialize().toString('hex'), function (err, response) { if (err !== null) return reject(err) return resolve(response) })

can you help me ? thank you, i think is contract error, but i dont konw .

@thontrancong
Copy link

@greggmojica I try and success. Thank many.

@shahzadthathal
Copy link

var privKey = new Buffer(process.env["PRIVATE_KEY"], 'hex');

How can I use new Buffer(key) in browser application? where should I get this file and include in my web app page?

@LF-DevJourney
Copy link

Refer to Send ERC20 token with web3

@ManUnit
Copy link

ManUnit commented Jun 1, 2018

I was deploy smart contract to my private network and then tested got output as below

node send.js
web3 version: 1.0.0-beta.34
num transactions so far: 10
Balance before send: 9.99999e+22 MFIL

Raw of Transaction:
{
"from": "0x82378cf137F5dF4FA730529eB79a4583EA605FA9",
"nonce": "0xa",
"gasPrice": "0xb2d05e00",
"gasLimit": "0x2dc6c0",
"to": "0xf1d28bac210b14b75e6ce1d529a1221c17579bfe",
"value": "0x0",
"data": "0xa9059cbb0000000000000000000000002c29f4c04d9acf4878a52c786b440698748783580000000000000000000000000000000000000000000000000000000000000001",
"chainId": 9559
}

(node:13335) UnhandledPromiseRejectionWarning: TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.
at Function.Buffer.from (buffer.js:183:11)
at new Buffer (buffer.js:158:17)
at main (/opt/tokens/send.js:42:19)
at
at process._tickCallback (internal/process/next_tick.js:188:7)
(node:13335) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:13335) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

JS Code as below :

require('dotenv').config();
var path = require('path');
var fs = require('fs');
var Web3 = require('web3');
var Tx = require('ethereumjs-tx');
const web3 = new Web3(Web3.givenProvider || "http://202.xxx.xxx.xxx:8545")
function financialMfil(numMfil) {
    return Number.parseFloat(numMfil / 1e3).toFixed(3);
}
const main = async () => {
    console.log(`web3 version: ${web3.version}`)
    var myAddress = "0x82378cf137F5dF4FA730529eB79a4583EA605FA9";
    var destAddress = "0x2c29f4c04D9Acf4878A52C786B44069874878358";
    var transferAmount = 1;
    var count = await web3.eth.getTransactionCount(myAddress);
    console.log(`num transactions so far: ${count}`);
    var abiArray = JSON.parse(fs.readFileSync(path.resolve(__dirname, './erc20_abi.json'), 'utf-8'));
    var contractAddress = "0xf1d28bac210b14b75e6ce1d529a1221c17579bfe";
    var contract = new web3.eth.Contract(abiArray, contractAddress, {
        from: myAddress
    });
    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 = 9559;
    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();

@PaulRBerg
Copy link

PaulRBerg commented Jun 1, 2018

Circumstance

I have followed all indications from here and StackOverflow, the transaction gets broadcasted but no tokens are transferred.

When I check the balance again, it's the same as before (10,000).

const Tx = require('ethereumjs-tx');

const config = require('../config');
const contract = require('../contract');
const web3 = require('../web3');

const main = async () => {
	try {
		const count = await web3.eth.getTransactionCount(config.accounts[0]);
		const nonce = web3.utils.toHex(count);
		const txValue = web3.utils.toHex(parseInt(process.argv[2], 10) || 10);

		const from = web3.utils.toChecksumAddress(config.accounts[0]);
		const to = web3.utils.toChecksumAddress(config.accounts[1]);

		const rawTx = {
			nonce: nonce,
			from: from,
			to: to,
			value: '0x0',
			gasLimit: '0x30D40', // 54,000
			gasPrice: '0x2CB417800', // 12 gwei
			data: contract.methods.transfer(to, txValue).encodeABI(),
			chainId: '0x03'
		};

		const privateKey = Buffer.from(config.private, 'hex');
		const tx = new Tx(rawTx);
		tx.sign(privateKey);
		const serializedTx = tx.serialize();

		const receipt = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'));
		console.log(`Receipt info:  ${JSON.stringify(receipt, null, '\t')}`);

		console.log(`From\'s balance after transfer: ${await contract.methods.balanceOf(from).call()}`);
		console.log(`To\'s balance after transfer: ${await contract.methods.balanceOf(to).call()}`);
	} catch (err) {
		console.log(err);
	}
};

main();

Tools

• node 9.3.0
• web3 1.0.0-beta.34
• os osx 13.13.3

Update

Solved. I was sending the tx to the other account by mistake, not to the contract. More details here.

@ManUnit
Copy link

ManUnit commented Jun 1, 2018

My error fixed ! just put private key

@ManUnit
Copy link

ManUnit commented Jun 1, 2018

@PaulRBerg you try use FradSer script above
seem to be you don't have ABI JSON

    var abiArray = JSON.parse(fs.readFileSync(path.resolve(__dirname, './erc20_abi.json'), 'utf-8'));
    var contract = new web3.eth.Contract(abiArray, contractAddress, {
        from: myAddress
    });

@PaulRBerg
Copy link

PaulRBerg commented Jun 2, 2018

@hs1gab I have it at line 4 const contract = require('../contract'); Inside that file:

const path = require('path');

const config = require('./config');
const web3 = require('./web3');

const ABI = require(path.join(__dirname, '..', 'build', 'contracts', 'PaulCoin.json')).abi;
const contract = new web3.eth.Contract(ABI, config.contract, { from: config.accounts[0] });

module.exports = contract;

As I previously stated, I can read the balance. I also can transfer ETH, only when trying to move tokens there are problems.

@ManUnit
Copy link

ManUnit commented Jun 2, 2018

@PaulRBerg Have you been move token by manual in Remix solidity by function transfer ? just for check account able to basic token move first

or in your code try change

 const txValue = web3.utils.toHex(parseInt(process.argv[2], 10) || 10); 
   
  // to

 const txValue = "12300000000000000000" ;

// or 

 var VALUE_TOKEN = "12300000000000000000" ; // cause of 18  decimal
  const txValue = web3.utils.toWei( VALUE_TOKEN , "ether") ;      

@marknguyen85
Copy link

@greggmojica
when call to

var data = contract.transfer.getData("0x2...", 10000, {from: "0x9..."});

then throw

RuntimeError: Function transfer is not constant: transfer, requires to sign transaction

@tangjielong
Copy link

thank you very mach!i get it.

@srishidev10
Copy link

@PaulRBerg
Your Code works For transfer .
But I want to transfer between two externally Owned accounts.
How to do that?

@ManUnit
Copy link

ManUnit commented Jul 5, 2018

@greggmojica

try use
var data = contract.methods.transfer(<to address>, <value>);

@tangjielong
Copy link

How do you use infura to get the user's key for (var private key = new Buffer ('f6da78c45601d9ae02fcdb161e44a15a99e1fb1aa931dd95366add5dec367e', hex'))

@PaulRBerg
Copy link

PaulRBerg commented Jul 30, 2018

@srishidev10 You can't have a contract sign a tx between two parties. You have these options though:

  1. Transfer the ether from account A to the contract and then, based on some logic, let B withdraw the funds.
  2. Use a token or WETH to get access to ERC20's approve function.

More on that here. However, I think we diverged. @greggmojica should close this issue if the initial problems were solved.

@nivida nivida closed this as completed Aug 9, 2018
@nivida
Copy link
Contributor

nivida commented Aug 9, 2018

Please ask further questions on https://ethereum.stackexchange.com/

@grinsteindavid
Copy link

// This is my code after one week trying a lot of tutorials. Thanks internet

const fs = require('fs');
const path = require('path');
const Web3API = require('web3');
const axios = require('axios');

/**

  • Fetch the current transaction gas prices from https://ethgasstation.info/

  • @return {object} Gas prices at different priorities
    */
    const getCurrentGasPrices = async () => {
    let response = await axios.get('https://ethgasstation.info/json/ethgasAPI.json');
    let prices = {
    low: response.data.safeLow / 10,
    medium: response.data.average / 10,
    high: response.data.fast / 10
    };

    console.log("\r\n");
    console.log(Current ETH Gas Prices (in GWEI):);
    console.log("\r\n");
    console.log(Low: ${prices.low} (transaction completes in < 30 minutes));
    console.log(Standard: ${prices.medium} (transaction completes in < 5 minutes));
    console.log(Fast: ${prices.high} (transaction completes in < 2 minutes));
    console.log("\r\n");

    return prices
    };

const main = async () => {
const web3 = new Web3API(new Web3API.providers.HttpProvider('https://mainnet.infura.io'));
const privateKey = "0x....";
const tokenAddress = "0x....";
const fromAddress = "0x....";
const toAddress = "0x....";

// ABI to transfer ERC20 Token
let abi = JSON.parse(fs.readFileSync(path.join(__dirname, '.', 'main_contract.json'), 'utf-8'));
// calculate ERC20 token amount ( 18 decimals )
let amount = 1;
let tokenAmount = web3.utils.toWei(amount.toString(), 'ether')
// Get ERC20 Token contract instance
let contract = new web3.eth.Contract(abi, tokenAddress, {
    from: fromAddress
});
// How many tokens do I have before sending?
let balance = await contract.methods.balanceOf(fromAddress).call();
console.log(`Balance before send: ${balance}`);
// EIP 155 - List of Chain ID's:
const chainList = {
    mainnet: 1,
    morden: 2,
    ropsten: 3,
    rinkeby: 4,
    ubiqMainnet: 8,
    ubiqTestnet: 9,
    rootstockMainnet: 30,
    rootstockTestnet: 31,
    kovan: 42,
    ethereumClassicMainnet: 61,
    ethereumClassicTestnet: 62,
    ewasmTestnet: 66,
    gethPrivateChains: 1337
};
// The gas price is determined by the last few blocks median gas price.
const avgGasPrice = await web3.eth.getGasPrice();
// current transaction gas prices from https://ethgasstation.info/
const currentGasPrices = await getCurrentGasPrices();
/**
 * With every new transaction you send using a specific wallet address,
 * you need to increase a nonce which is tied to the sender wallet.
 */
let nonce = web3.eth.getTransactionCount(fromAddress);
// Will call estimate the gas a method execution will take when executed in the EVM without.
let estimateGas = await web3.eth.estimateGas({
    "value": '0x0', // Only tokens
    "data": contract.methods.transfer(toAddress, tokenAmount).encodeABI(),
    "from": fromAddress,
    "to": toAddress
});
console.log({
    estimateGas: estimateGas
});
// Build a new transaction object.
const transaction = {
    "value": '0x0', // Only tokens
    "data": contract.methods.transfer(toAddress, tokenAmount).encodeABI(),
    "from": fromAddress,
    "to": toAddress,
    "gas": web3.utils.toHex(estimateGas * 1.10),
    "gasLimit": web3.utils.toHex(estimateGas * 1.10),
    "gasPrice": web3.utils.toHex(Math.trunc(currentGasPrices.medium * 1e9)),
    "chainId": web3.utils.toHex(chainList.mainnet)
};
// Creates an account object from a private key.
const senderAccount = web3.eth.accounts.privateKeyToAccount(privateKey);
/**
* This is where the transaction is authorized on your behalf.
* The private key is what unlocks your wallet.
*/
const signedTransaction = await senderAccount.signTransaction(transaction);
console.log({
    transaction: transaction,
    amount: amount,
    tokenAmount: tokenAmount,
    avgGasPrice: avgGasPrice,
    signedTransaction: signedTransaction
});

// We're ready! Submit the raw transaction details to the provider configured above.
try {
    const receipt = await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction);

    console.log({
        receipt: receipt
    });
    
} catch (error) {
    console.log({
        error: error.message
    });
}

};

main();

@Cucak
Copy link

Cucak commented Mar 2, 2021

What I dont understand is there any difference when you send token from one wallet address to other wallet address, and when you want to basically buy token with a wallet address from the smart contract of the token?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests