How to send an ERC20 token with web3js - javascript
I'm currently using the 0.2x.x version of the Web3 JavaScript API. I deployed my custom ERC20 token by creating smart contract in solidity (on REMIX IDE).
I installed the MetaMask and had a test on https://wallet.ethereum.org/ to send some custom ERC token to another my account. It worked well.
I want to add the 'send custom ERC20 Token' function in my JavaScript code using Web3js.
Here is my code below.
var http = require('http');
var Web3 = require('web3');
var Tx = require('ethereumjs-tx');
var abi = [{"...."}];
var data = '0x00..';
var contract_addr = '0x00..';
var owner = '0x00..';
var web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/"));
web3.eth.getBlock("latest", (error, result) => {
//console.log('error:', error);
//console.log('results', result);
});
var myContract = web3.eth.contract(abi);
var myContractInstance = myContract.at(address);
eb3.eth.getDefaultAccount = owner;
var defaultAccount = web3.eth.getDefaultAccount;
console.log('DefaultAccount => ', defaultAccount);
var total = myContractInstance.totalSupply();
var balance = myContractInstance.balanceOf(defaultAccount);
console.log('DefulatAccount total => ',total);
console.log('DefaultAccount balance => ',balance);
var to = '0x00..';
var isAddress = web3.isAddress(to);
console.log('isAddress(to) => ',isAddress);
console.log('balanceOf(to) => ',myContractInstance.balanceOf(to));
I'm working on the 'Ropsten Testnet' and I sent some 'ether' for test using sendRawTransaction(). But what I want to do is just sending my custom ERC20 token. not the ether. How can I send my own token in this script? I have no idea. I tried to use sendTransaction() like below.
var rawTx = {
from : defaultAccount,
nonce : nonceHex,
gasPrice : gasPriceHex,
gas : gasHex,
to : to,
value : 100,
data : data
};
web3.eth.sendTransaction(rawTx, function(err, transactionHash) {
if (!err)
console.log('transactionHash => ',transactionHash);
else
console.log(err);
});
I continuously received the error.
Error: Invalid JSON RPC response: ""
at Object.InvalidResponse (/Users/rachel/dev/test/node_modules/web3/lib/web3/errors.js:38:16)
at XMLHttpRequest.request.onreadystatechange (/Users/rachel/dev/test/node_modules/web3/lib/web3/httpprovider.js:119:24)
at XMLHttpRequestEventTarget.dispatchEvent (/Users/rachel/dev/test/node_modules/xhr2/lib/xhr2.js:64:18)
at XMLHttpRequest._setReadyState (/Users/rachel/dev/test/node_modules/xhr2/lib/xhr2.js:354:12)
at XMLHttpRequest._onHttpResponseEnd (/Users/rachel/dev/test/node_modules/xhr2/lib/xhr2.js:509:12)
at IncomingMessage.<anonymous> (/Users/rachel/dev/test/node_modules/xhr2/lib/xhr2.js:469:24)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1056:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
I really can't understand what is wrong with it. Please let me know some way to deal with this. Thanks!
Take EOS token transfering as the example.
Below code need web3 and ethereumjs-tx. If you've not install them, install them with npm install web3 ethereumjs-tx
var Tx = require('ethereumjs-tx');
var Web3 = require('web3')
var web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:8545/'))
// set token source, destination and amount
var myAddress = "0xaa597b7e8aaffe9f2a187bedb472ef3455957560"
var toAddress = "0xa013927bffe9e879134061b9330a01884a65497c"
var amount = web3.utils.toHex(1e16)
// get transaction count, later will used as nonce
web3.eth.getTransactionCount(myAddress).then(function(v){console.log(v); count = v})
// set your private key here, we'll sign the transaction below
var privateKey = new Buffer('6d...', 'hex')
// Get abi array here https://etherscan.io/address/0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0#code
var abiArray = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint128"}],"name":"push","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"mint","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint128"}],"name":"pull","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","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"},{"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"}]
// Here you may get the abicode from a string or a file, here is a string case
// var abiArray = JSON.parse('[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint128"}],"name":"push","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"mint","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint128"}],"name":"pull","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","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"},{"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"}]', 'utf-8')
var contractAddress = '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0'
var contract = new web3.eth.Contract(abiArray, contractAddress, {from: myAddress})
var rawTransaction = {"from":myAddress, "gasPrice":web3.utils.toHex(2 * 1e9),"gasLimit":web3.utils.toHex(210000),"to":contractAddress,"value":"0x0","data":contract.methods.transfer(toAddress, amount).encodeABI(),"nonce":web3.utils.toHex(count)}
var transaction = new Tx(rawTransaction)
transaction.sign(privateKey)
web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex'))
// check the balance
contract.methods.balanceOf(myAddress).call().then(function(balance){console.log(balance)})
You also can check the transaction with https://etherscan.io.
After the transaction send, you can check it with https://etherscan.io/address/0xaa597b7e8aaffe9f2a187bedb472ef3455957560#tokentxns, and you'll see the pending transaction as below on the Transactions filed, but you cannot see it in the Token Transfers field.
Wait about 1 minute, you can see the successed on both Transactions filed and the Token Transfers field.
Error: Invalid JSON RPC response: "" means web3 cant connect to rpc node.
Try running one with ::
-for testnet
geth --testnet --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --rpccorsdomain '*' --rpcapi personal,admin,db,eth,net,web3,miner,shh,txpool,debug --ws --wsaddr 127.0.0.1 --wsport 8546 --wsorigins '*' --wsapi personal,admin,db,eth,net,web3,miner,shh,txpool,debug --maxpeers 25 0 --gasprice 100
-for mainnet
geth --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --rpccorsdomain '*' --rpcapi personal,admin,db,eth,net,web3,miner,shh,txpool,debug --ws --wsaddr 127.0.0.1 --wsport 8546 --wsorigins '*' --wsapi personal,admin,db,eth,net,web3,miner,shh,txpool,debug --maxpeers 25 0 --gasprice 100
Now in your case (using infura testnet node), get a id from infura.io.
It should be like this ::
https://ropsten.infura.io/id
You need to call the transfer method of the ERC20 contract.
e.g.:
myContractInstance.methods.transfer(toAddress, amount);
And in your raw transaction object:
You don't need the amount
To address should be to the contract (not the toAddress in the method call)
e.g.:
var rawTx = {
from : defaultAccount,
nonce : nonceHex,
gasPrice : gasPriceHex,
gas : gasHex,
to : <contractAddress>,
data : data
};
Well you can try something like this-:
`myContractInstance.transfer(to,amount, {gas:estimateGas,
gasPrice:gasPrice,from:fromAddr, nonce: nonceis}, function(err,txhash)
{
console.log("error: "+err);
console.log("txhash: "+txhash);
}
`
Here 'to' is the address to whom you want to send tokens
'amount' amount of tokens you want to send
'estimateGas' gas limit you want to put of the transaction execution
'gasPrice' price of each gas unit in terms of wei
'fromAddr' the address from where you want to send these tokens. As the transaction will be signed using this address, this should be the address selected in metamask or passed to infura
'nonceis' nonce for the transaction
We can do it with only 'ethers'.
In this case, I use backend api with node js.
const fs = require('fs');
const express = require('express');
const router = express.Router();
const { ethers, BigNumber } = require('ethers');
const ethUtil = require('ethereumjs-util');
const BridgeEth = require("../../client/src/components/contract/EthBridge.json");
const BridgeBsc = require("../../client/src/components/contract/BridgeBsc.json");
const addresses = require("../../client/src/components/contract/config.json");
const eth_bridge = addresses.eth_bridge;
const bsc_bridge = addresses.bsc_bridge;
const net_config = require("../../net.config.json");
const ethnet = net_config.eth_url;
const bscnet = net_config.bsc_url;
const eth_provider = new ethers.providers.JsonRpcProvider(ethnet);
const bsc_provider = new ethers.providers.JsonRpcProvider(bscnet);
const eth_contract = new ethers.Contract(eth_bridge, BridgeEth, eth_provider);
const bsc_contract = new ethers.Contract(bsc_bridge, BridgeBsc, bsc_provider);
var privateKey = fs.readFileSync('./secret', 'utf-8');
const adminaccount = {
publicKey: net_config.admin_public_key,
privateKey: privateKey
}
console.log(`Admin account is ${adminaccount.publicKey}`);
const adminEthWallet = new ethers.Wallet(adminaccount.privateKey, eth_provider);
const adminBscWallet = new ethers.Wallet(adminaccount.privateKey, bsc_provider);
const signedEthContract = eth_contract.connect(adminEthWallet);
const signedBscContract = bsc_contract.connect(adminBscWallet);
const sig = "0x6162636400000000000000000000000000000000000000000000000000000000";
router.post('/eth2bsc', async (req, res) => {
var account = req.body.account;
var amount = req.body.amount;
var signature = req.body.signature;
var msg = req.body.hash;
const isValidAddress = ethUtil.isValidAddress(account);
const isValidAmount = amount > 0;
const isValidSign = ethUtil.isHexPrefixed(String(signature));
const isValidHash = ethUtil.isHexPrefixed(String(msg));
if (!(isValidAddress && isValidAmount && isValidSign && isValidHash)) {
return res.status(500).json({ step: 1, message: `Security error! Server received invalid prams!${isValidAddress}, ${amount}, ${isValidSign}, ${isValidHash}` });
}
var msgBuffer = '';
var msgHash = '';
var signatureBuffer = '';
try {
msgBuffer = ethUtil.toBuffer(msg);
msgHash = ethUtil.hashPersonalMessage(msgBuffer);
signatureBuffer = ethUtil.toBuffer(signature);
} catch (e) {
return res.status(500).json({ step: 1, message: 'Security error! Request with invalid params!' })
}
const signatureParams = ethUtil.fromRpcSig(signatureBuffer);
const publicKey = ethUtil.ecrecover(msgHash, signatureParams.v, signatureParams.r, signatureParams.s);
const adddressBuffer = ethUtil.publicToAddress(publicKey);
const address = ethUtil.bufferToHex(adddressBuffer);
console.log(`recvered address is ${address}`);
const isMatched = account.toLowerCase() == address.toLowerCase();
if (!isMatched) {
return res.status(500).json({ step: 1, message: 'Security error! Transaction caller is not signer!' })
}
console.log(`I will burn BSCFloki from ${account}`)
try {
var tx = await signedEthContract.burn(account, BigNumber.from(String(amount * Math.pow(10, 18))), 0, sig)
console.log(tx.hash);
console.log("First transaction successed(ETHFloki burned)");
} catch (e) {
console.log("Transaction to burn ETHFloki faild");
return res.status(500).json({ step: 1, message: 'Transaction Faild! \nCheck your account and token balance.' })
}
console.log(`I will mint BSCFloki to ${account}`)
try {
var tx1 = await signedBscContract.mint(account, account, BigNumber.from(String(amount * Math.pow(10, 18))), 0, sig);
console.log(tx1.hash);
console.log("Second transaction successed(BSCFloki minted)");
} catch (e) {
console.log("Transanction to mint BSCFloki faild");
return res.status(500).json({ step: 2, message: 'Transaction Faild! \nCheck your account.' })
}
return res.send(`Success! \n ${amount} ETHFloki converted to ${amount} BSCFloki in your wallet.`);
});
router.post('/bsc2eth', async (req, res) => {
var account = req.body.account;
var amount = req.body.amount;
var signature = req.body.signature;
var msg = req.body.hash;
const isValidAddress = ethUtil.isValidAddress(account);
const isValidAmount = amount > 0;
const isValidSign = ethUtil.isHexPrefixed(String(signature));
const isValidHash = ethUtil.isHexPrefixed(String(msg));
if (!(isValidAddress && isValidAmount && isValidSign && isValidHash)) {
return res.status(500).json({ step: 1, message: 'Security error! Server received invalid prams!' });
}
var msgBuffer = '';
var msgHash = '';
var signatureBuffer = '';
try {
msgBuffer = ethUtil.toBuffer(msg);
msgHash = ethUtil.hashPersonalMessage(msgBuffer);
signatureBuffer = ethUtil.toBuffer(signature);
} catch (e) {
return res.status(500).json({ step: 1, message: 'Security error! Request with invalid params!' })
}
const signatureParams = ethUtil.fromRpcSig(signatureBuffer);
const publicKey = ethUtil.ecrecover(msgHash, signatureParams.v, signatureParams.r, signatureParams.s);
const adddressBuffer = ethUtil.publicToAddress(publicKey);
const address = ethUtil.bufferToHex(adddressBuffer);
console.log(`recvered address is ${address}`);
const isMatched = account.toLowerCase() == address.toLowerCase();
if (!isMatched) {
return res.status(500).json({ step: 0, message: 'Security error! Transaction caller is not signer!' })
}
console.log(`I will burn BSCFloki from ${account}`)
try {
var tx = await signedBscContract.burn(account, BigNumber.from(String(amount * Math.pow(10, 18))), 0, sig)
console.log(tx.hash);
console.log("First transaction successed(BTK burned)");
} catch (e) {
console.log("Transaction to burn ETHFloki faild");
return res.status(500).json({ step: 1, message: 'Transaction Faild! \nCheck your account and token balance.' })
}
console.log(`I will mint ETHFloki to ${account}`)
try {
var tx1 = await signedEthContract.mint(account, account, BigNumber.from(String(amount * Math.pow(10, 18))), 0, sig);
console.log(tx1.hash);
console.log("Second transaction successed(ETHFloki minted)");
} catch (e) {
console.log("Transaction to mint ETHFloki faild");
return res.status(500).json({ step: 2, message: 'Transaction Faild! \nCheck your account.' })
}
return res.send(`Success! \n ${amount} BSCFloki converted to ${amount} ETHFloki in your wallet.`);
});
module.exports = router;
This api is sign client's request and send transaction with signed wallet and its private key.
Related
nodejs web3 bsc bep20 token transfer no confirmation
I'm trying to transfer a BEP-20 token on BSC from one Wallet to Another. I actually had it at one point and somehow messed up while doing code cleanup. Anway, I need some help. When I send my transaction I never get a confirmation. I get a hash for example : 0xd18ee37686b00d45edb9974d8a119534f3403052e3ed4908ac8ca80bde385416 But it never goes anywhere. I've beat my head on the wall with this for two days, any help would be greatly appreciated. - Note Endpoint and Private Key are fake // Ethereum javascript libraries needed var Web3 = require('web3') var Tx = require("ethereumjs-tx").Transaction; const Common = require('ethereumjs-common'); const mysql = require('mysql'); //KLUV Contract Address KLUV - BSC const _ContractAddress_ = '0x3A68A9Cd188C324a45c06866eFD1C79605B66827'; const _ContractABI_ = JSON.parse('[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getunlockedAfter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedPeriodOver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawLockedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]'); //To Wallet Address const _ToWalletAddress_ = '0x76D52CF51D9a4B8C84Bf01b7AA3f801c52A328D8'; //My MetaMask Wallet const _FromWalletAddress_ = '0xDeBCBca7f21aB70DA4e7860a112FEB3d8Fd04db5'; //My MetaMask Private Key const _FromWalletPrivateKey_ = 'f777980edfc1c92446XXXXXXXXXXXXXXXe615ffcccc0744f0a4054c8f924773d'; //Node URL const BSCNode = 'https://nd-098-532-742.p2pify.com/super_secret_address'; const web3 = new Web3(new Web3.providers.HttpProvider(BSCNode)); const main = async () => { console.log(`web3 version: ${web3.version}`) // Who holds the token now? var senderWalletAddress = _FromWalletAddress_; // Who are we trying to send this token to? var receiverWalletAddress = _ToWalletAddress_; // The address of the contract which created MFIL var contractAddress = _ContractAddress_; var contract = new web3.eth.Contract(_ContractABI_, contractAddress, { from: senderWalletAddress }); // How many tokens do I have before sending? var balance = await contract.methods.balanceOf(senderWalletAddress).call(); console.log(`Balance before send: ${balance} sKLUV\n------------------------`); // Use Gwei for the unit of gas price var gasPriceGwei = 5; var gasLimit = 5000000; // .00000001 KLUV var transferAmount = 1; // Determine the nonce - This isn't always good, you need to keep track of it var count = await web3.eth.getTransactionCount(senderWalletAddress); console.log(`num transactions so far: ${count}`); /* Override count - especially if testing */ count = 77; var rawTransaction = { "from": senderWalletAddress, "nonce": "0x" + count.toString(16), "gasPrice": web3.utils.toHex(gasPriceGwei * 1e9), "gasLimit": web3.utils.toHex(gasLimit), "to": contractAddress, "value": "0x0", "chainId": 56, "data": contract.methods.transfer(receiverWalletAddress, transferAmount).encodeABI(), }; console.log(`Raw of Transaction: \n${JSON.stringify(rawTransaction, null, '\t')}\n------------------------`); // Create Buffer containing hex of private key var privKey = new Buffer.from(_FromWalletPrivateKey_, 'hex'); /* Define What Block Chain we're using */ const chain = Common.default.forCustomChain( 'mainnet', { name: 'bnb', networkId: 56, chainId: 56 }, 'petersburg' ) /* generate transaction including my block chain */ var tx = new Tx(rawTransaction, {common: chain}); /* sign the transaction with my buffered private key */ tx.sign(privKey); /* Serialize the result */ var serializedTx = tx.serialize(); /* Get Ready to send */ console.log(`Attempting to send signed tx: ${serializedTx.toString('hex')}\n------------------------`); /* Limit the number of confirms we're looking for */ let numberOfConfirms = 5; web3.eth.transactionConfirmationBlocks = numberOfConfirms; /* Use Event Method so we can see where things are hanging up */ web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')) .on("sending", (payload) => { console.log('sending '); console.log(payload); }) .on("sent", (payload) => { console.log('Sent Payload'); console.log(payload); }) .on('transactionHash', (transactionHash) => { console.log('Received Transaction hash'); console.log(transactionHash); }) .on("receipt", (receipt) => { console.log('Received Receipt'); console.log(`Receipt info: \n${JSON.stringify(receipt, null, '\t')}\n------------------------`); }) .on("confirmation", (confNumber, receipt, latestBlockHash) => { console.log('Received Confirmation ', confNumber); if (confNumber == numberOfConfirms) { // The balance may not be updated yet, but let's check contract.methods.balanceOf(senderWalletAddress).call().then((balance) => { console.log(`Balance after send: ${balance} sKLUV`); }); } console.log(confNumber, receipt, latestBlockHash); }) .on('error', err => { console.log('Error Sending Transaction'); console.log(err.message); }).catch(reason => { console.log('Promise failed in catch'); console.log(reason); }); }; main();
the only thing I see chainId in rawTransaction is not in hex format. should be "chainId":web3.utils.toHex(56)
Getting Error: Returned error: Must be authenticated! , while sending erc20 code using web3.js
const fs = require('fs'); let web3 = new Web3(new Web3.providers.HttpProvider('http:127.0.0.1')) const abi = fs.readFileSync('erc20_abi.json', 'utf-8') const contractAddress = '0xB4...' const privateKey = '...' let contract = new web3.eth.Contract(JSON.parse(abi), contractAddress); let transfer = contract.methods.transfer("0xd...", 10); let encodedABI = transfer.encodeABI(); var tx = { from: "0xF...", to: contractAddress, gas: 2000000, data: encodedABI }; web3.eth.accounts.signTransaction(tx, privateKey).then(signed => { var tran = web3.eth.sendSignedTransaction(signed.rawTransaction); tran.on('confirmation', (confirmationNumber, receipt) => { console.log('confirmation: ' + confirmationNumber); }); tran.on('transactionHash', hash => { console.log('hash'); console.log(hash); }); tran.on('receipt', receipt => { console.log('reciept'); console.log(receipt); }); tran.on('error', console.error); }); I am using the above code to send ERC20 tokens from account to another account, Its throwing this error UnhandledPromiseRejectionWarning: Error: Returned error: Must be authenticated
I have figured it out I am using wrong rpc provider, changing the Rpc provider fixes this issue.
Why "invalid sender" (-32000) when trying to deploy an Ethereum smart contract from node script?
Trying to deploy my smart contract to the rinkeby network but I am receiving this error message { code: -32000, message: 'invalid sender' }. I tried deploying my contract via Remix and it worked fine but I am a bit lost on why I am receiving this error. const HDWalletProvider = require("#truffle/hdwallet-provider"); // "^1.2.4" const Web3 = require("web3"); // "^1.3.4" const compiledFactory = require("./build/factory.json"); const abi = compiledFactory.abi; const bytecode = compiledFactory.evm.bytecode.object; const provider = new HDWalletProvider({ mnemonic: { phrase: "twelve word mnemonic phrase twelve word mnemonic phrase twelve word mnemonic phrase", }, providerOrUrl: "https://rinkeby.infura.io/v3/12345678", }); const web3 = new Web3(provider); const deploy = async () => { const accounts = await web3.eth.getAccounts(); console.log("Attempting to deploy from account", accounts[0]); try { const result = await new web3.eth.Contract(abi) .deploy({ data: bytecode }) .send({ from: accounts[0], gas: "1000000" }); console.log("Contract deployed to", result.options.address); } catch (e) { console.error(e); } }; deploy();
Got it to work. Problem is, the transaction has to be signed before sending it. Here is the updated deploy function. const deploy = async () => { const accounts = await web3.eth.getAccounts(); const deploymentAccount = accounts[0]; const privateKey = provider.wallets[ deploymentAccount.toLowerCase() ].privateKey.toString("hex"); console.log("Attempting to deploy from account", deploymentAccount); try { let contract = await new web3.eth.Contract(abi) .deploy({ data: bytecode, arguments: [], }) .encodeABI(); let transactionObject = { gas: 4000000, data: contract, from: deploymentAccount, // chainId: 3, }; let signedTransactionObject = await web3.eth.accounts.signTransaction( transactionObject, "0x" + privateKey ); let result = await web3.eth.sendSignedTransaction( signedTransactionObject.rawTransaction ); console.log("Contract deployed to", result.contractAddress); } catch (e) { console.error(e); } process.exit(1); };
Listing NFT on OpenSea via JS API: Failed to extract transfer calldata Error 400
I am trying to use the OpenSea JavaScript API in order to list NFTs for sale automatically. I can't seem to figure out why I keep getting the error Error: API Error 400: ['Failed to extract transfer calldata']. Perhaps I have not entered some data correctly? My code is adapted from this example. SOURCE const opensea = require("opensea-js"); const OpenSeaPort = opensea.OpenSeaPort; const Network = opensea.Network; const MnemonicWalletSubprovider = require("#0x/subproviders") .MnemonicWalletSubprovider; const RPCSubprovider = require("web3-provider-engine/subproviders/rpc"); const Web3ProviderEngine = require("web3-provider-engine"); const MNEMONIC = "SECRET ..."; const NODE_API_KEY = "FROM INFURA"; const isInfura = true; //const FACTORY_CONTRACT_ADDRESS = process.env.FACTORY_CONTRACT_ADDRESS; const NFT_CONTRACT_ADDRESS = "0x495f947276749Ce646f68AC8c248420045cb7b5e"; const OWNER_ADDRESS = "0x3eb8eea9565418281f4cae934dd69e7ff2bb5949"; const NETWORK = "mainnet"; const API_KEY = process.env.API_KEY || ""; // API key is optional but useful if you're doing a high volume of requests. const BASE_DERIVATION_PATH = `44'/60'/0'/0`; const mnemonicWalletSubprovider = new MnemonicWalletSubprovider({ mnemonic: MNEMONIC, baseDerivationPath: BASE_DERIVATION_PATH, }); const network = NETWORK === "mainnet" || NETWORK === "live" ? "mainnet" : "rinkeby"; const infuraRpcSubprovider = new RPCSubprovider({ rpcUrl: isInfura ? "https://" + network + ".infura.io/v3/" + NODE_API_KEY : "https://eth-" + network + ".alchemyapi.io/v2/" + NODE_API_KEY, }); const providerEngine = new Web3ProviderEngine(); providerEngine.addProvider(mnemonicWalletSubprovider); providerEngine.addProvider(infuraRpcSubprovider); providerEngine.start(); const seaport = new OpenSeaPort( providerEngine, { networkName: NETWORK === "mainnet" || NETWORK === "live" ? Network.Main : Network.Rinkeby, apiKey: API_KEY, }, (arg) => console.log(arg) ); exports.helloWorld = async (req, res) => { // Example: simple fixed-price sale of an item owned by a user. console.log("Auctioning an item for a fixed price..."); try { const fixedPriceSellOrder = await seaport.createSellOrder({ asset: { tokenId: "28370143653034713195993216915191765879963367987017833025925208213530804748289", tokenAddress: NFT_CONTRACT_ADDRESS, }, startAmount: 0.1, expirationTime: 0, accountAddress: OWNER_ADDRESS, }); console.log( `Successfully created a fixed-price sell order! ${fixedPriceSellOrder.asset.openseaLink}\n` ); } catch (error) { console.log("ERROR",error); } }; FULL LOGS WHERE I GOT DATA ASSET URL
What is your Token Standard? If it is not ERC721, you need to specify it as your schemaName inside the asset object, like this : const fixedPriceSellOrder = await seaport.createSellOrder({ asset: { tokenId: "28370143653034713195993216915191765879963367987017833025925208213530804748289", tokenAddress: NFT_CONTRACT_ADDRESS, schemaName: "ERC1155" }, startAmount: 0.1, expirationTime: 0, accountAddress: OWNER_ADDRESS, }); You can find Token Standard in Details tab, on Opensea asset page : Remove the dash and you're good. ERC1155 was fine for me.
Metamask returns RPC Error: Error: [ethjs-rpc] rpc error with payload {"id":5715960965837,"jsonrpc":"2.0","params":
I have this code that allows me to make a purchase of tokens with web3, apparently if the transaction is validated but when I click confirm, the following error appears: inpage.js:1 MetaMask - RPC Error: Error: [ethjs-rpc] rpc error with payload {"id":5715960965839,"jsonrpc":"2.0","params":["0xf8ac178504a817c8008301022794cfeb869f69431e42cdb54a4f4f105c19c080a60180b844095ea7b3000000000000000000000000c89ce4735882c9f0f0fe26686c53074e09b0d55000000000000000000000000000000000000000000000000000000000000f4240820557a07ff18aba5ab0a8080f4a4b29e8736c4ded84e09cec8f66eba186995a6b22261fa041fd2e3351985a3b0a4e1ec9ef1be79c3513170810569b78ba9f238d36e781fa"],"method":"eth_sendRawTransaction"} [object Object] try to uninstall the extension and reinstall it as mentioned in other places, but without getting any results this is my code /* 'metamask': */ const web3 = new Web3(window["ethereum"]); const USDT_ADDRESS = "XxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; const ORION_SALE_ADDRESS = "XxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; const usdtContract = new web3.eth.Contract(IRC20_JSON.abi, USDT_ADDRESS); const saleContract = new web3.eth.Contract( ORION_SALE_JSON.abi, ORION_SALE_ADDRESS ); let userWallet; const getAddress = async () => { try { const accounts = await window.ethereum.enable(); userWallet = accounts[0]; console.log(accounts, ORION_SALE_JSON); if (!userWallet) { document.getElementById("msg").innerHTML = "Oops, we can't seem to find the address of your wallet. Please, log in into your metamask account using the chrome extension and then refresh the page"; } else { document.getElementById("msg").innerHTML = "Your wallet have been successfully added"; } } catch (error) { console.log(error); } }; getAddress(); //buyTokenFunction const myfunction = async () => { let inputVal = document.getElementById("myInput").value; if (inputVal !== "") { usdtContract.methods .approve(ORION_SALE_ADDRESS, (inputVal * 1e6).toFixed(0)) .send({ from: userWallet }) .once("transactionHash", (hash) => { saleContract.methods .buyTokens(userWallet, USDT_ADDRESS, (inputVal * 1e6).toFixed(0)) .send({ from: userWallet, gas: 10000000 }, (_) => { // Waiting for the transaction to be mined }) .then((_) => { // Success }); }); } };
Trace inputVal (or output to the console). Or even better is the whole expression: (inputVal * 1e6).toFixed(0) Determine in which method the error occurs: approve or buyToken.