Bit of context; this was working fine on Goerli just a few days a go but the script now works intermittently. At the moment im thinking its down to one of the following:
Node issue - currently using infura and have tried changing it across other public RPCS but didn't work any better
Web3 issue - not sure if something is now outdated
Nonce issue with wallets, not sure if there is something obvious in the code here that is causing my Txs to get stuck and as such never return a receipt
For some reason this was all working fine last night after having not worked all day. Bit stuck as to what i could be doing wrong tbh. The logic is that based on a mempool tx, the sendTx function is invoked with the 'targetAddress' param which contains all the necessary objects to replicate the tx which i am tracking.
Tx.js:
const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
process.removeAllListeners('warning');
require('dotenv').config();
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET;
const web3 = new Web3(INFURA_URL_TESTNET);
const BN = web3.utils.BN;
// Tx details:
const sendTx = async (targetAddress) => {
const address = targetAddress.address;
const ethAmmount = targetAddress.value;
const data = targetAddress.input;
const gasLimit = targetAddress.gas;
//const gasPrice = targetAddress.gasPrice - web3.utils.toWei('1', 'gwei');
const maxFeePerGas = targetAddress.maxFeePerGas //- 1000000;
const maxPriorityFeePerGas = targetAddress.maxPriorityFeePerGas //- 1000000;
const privKey = targetAddress.privKey;
const from = targetAddress.from;
const _txCount = await web3.eth.getTransactionCount(from);
const createTransaction = await web3.eth.accounts.signTransaction(
{ to: address,
from: from,
data: data,
gas: gasLimit,
value: ethAmmount,
nonce: _txCount,
maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: maxPriorityFeePerGas,
},
privKey,
);
// Send Tx and Wait for Receipt
const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
//const transaction = await web3.eth.getTransaction(createReceipt.transactionHash);
console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
};
module.exports = {sendTx};
The code stops at the await .sendSignedTx and doesn't return a receipt. As i said, this does work exactly as expected sometimes and i can figure out why sometimes it works and sometimes it doesn't?
Thanks everyone!
Since you are using web3js, you have to handle the event promise chain when calling sendSignedTransaction and log all the payloads. That will tell you the reason for it not being broadcast. Could be a network error, gas issue, maybe nonce .e.t.c.
See https://web3js.readthedocs.io/en/v1.2.11/callbacks-promises-events.html#callbacks-promises-events
Related
I've been trying to get a transaction to execute on Polygon but it's been failing with the following error:
reason: 'processing response error',
code: 'SERVER_ERROR',
body: '{"jsonrpc":"2.0","id":89,"error":{"code":-32000,"message":"transaction underpriced"}}',
This error only occurs on Polygon and it only occurs when using the Gnosis SDK. I've tested it using the Gnosis UI and it executes successfully. I've also tested it using the Gnosis SDK on rinkeby and that works as well.
Here is the code that fails:
const infuraProvider = new ethers.providers.JsonRpcProvider(RPC_PROVIDER);
const wallet = new ethers.Wallet(`0x${PRIVATE_KEY}`, infuraProvider);
const owner1 = wallet.connect(infuraProvider);
const ethAdapterOwner1 = new EthersAdapter({ ethers, signer: owner1 });
const safeSdkInstance = await Safe.create({
ethAdapter: ethAdapterOwner1,
safeAddress: GNOSIS_SAFE_ADDR,
});
const contract = new ethers.Contract(contractJson.address, contractJson.abi, owner1);
const tx = {
to: contract.address,
value: '0',
data: contract.interface.encodeFunctionData('mint', ['[wallet address here]', '[token id here]']),
};
const safeTransaction = await safeSdkInstance.createTransaction(tx);
const executeTxResponse = await safeSdkInstance.executeTransaction(safeTransaction);
Other things I've tried:
Adding a gasPrice - making that gas price incredibly large
Adding a gasLimit
Changing RPC_PROVIDER from an infura provider to a public one
Calling a different function - I tried calling my contracts burn function and it came back with the exact same error
I did notice that even when providing a gasPrice the error I get back says that the transaction provided had a gasPrice of null. But when logging the safeTransaction object it shows a gasPrice is generated by the createTransaction function. So something must be going wrong in the executeTransaction function
Visual Studio Code 1.66.2
ganache v7.1.0 (#ganache/cli: 0.2.0, #ganache
I am new to Solidity and this is my first example I am trying out.
I am trying to get noticed when there is a swap event in the Uniswap Pool "ETH-APE" using:
uPair.events.Swap
The code seems to start where: Waiting for swaps...
I can see on Uniswap itself that there is regular swaps but the swap event seems to not trigger where the console.log should show: someone swapped now!
I have started this blockchain successfully with the command like this:
Notice: I have a real apikey from alchemy and a real mnemonic from ganache-cli
ganache-cli -f wss://eth-mainnet.alchemyapi.io/v2/myAPIkey --mnemonic "word1 word2 word3 etc" -p 7545
I have just followed some examples and are not sure exactly what I am doing:
As I am a beginner I must also ask about ganache. As I have understand this is a "Fake and local Sandboxed" blockchain just existing on my computer?
I think I understand that I start ganache-cli on my computer but are not sure if the uPair.events.Swap listen to my local blockchain which is not the REAL blockchain and this is because the swap event is not triggered. If that is the case then that is what I wonder what I am missing?
(I am not even sure I need ganache to listen to this swap event?)
I am not sure what the alchemyapi.io with myAPIkey is doing in the command to start the local ganache-cli where in the same command I use the mnemonic which has been generated from ganache?
// -- HANDLE INITIAL SETUP -- //
require("dotenv").config();
const Web3 = require('web3')
const IERC20 = require('#openzeppelin/contracts/build/contracts/ERC20.json')
const IUniswapV2Pair = require("#uniswap/v2-core/build/IUniswapV2Pair.json")
const IUniswapV2Factory = require("#uniswap/v2-core/build/IUniswapV2Factory.json")
const { ChainId, Token } = require("#uniswap/sdk")
let web3 = new Web3('ws://127.0.0.1:7545')
const main = async () => {
const _eth_address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const _apecoin_address = "0x4d224452801aced8b2f0aebe155379bb5d594381";
const _uniswap_factory_address = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
const uFactory = new web3.eth.Contract(IUniswapV2Factory.abi, _uniswap_factory_address) // UNISWAP FACTORY CONTRACT
const { token0Contract, token1Contract, token0, token1 } = await getTokenAndContract(_eth_address, _apecoin_address)
let uPair = await getPairContract(uFactory, token0.address, token1.address)
console.log("Waiting for swaps...");
uPair.events.Swap({}, async () => {
console.log("someone swapped now!");
})
}
async function getPairAddress(_V2Factory, _token0, _token1) {
const pairAddress = await _V2Factory.methods.getPair(_token0, _token1).call()
return pairAddress
}
async function getPairContract(_V2Factory, _token0, _token1) {
const pairAddress = await getPairAddress(_V2Factory, _token0, _token1)
const pairContract = new web3.eth.Contract(IUniswapV2Pair.abi, pairAddress)
return pairContract
}
async function getTokenAndContract(_token0Address, _token1Address) {
const token0Contract = new web3.eth.Contract(IERC20.abi, _token0Address)
const token1Contract = new web3.eth.Contract(IERC20.abi, _token1Address)
const token0 = new Token(
ChainId.MAINNET,
_token0Address,
18,
await token0Contract.methods.symbol().call(),
await token0Contract.methods.name().call()
)
const token1 = new Token(
ChainId.MAINNET,
_token1Address,
18,
await token1Contract.methods.symbol().call(),
await token1Contract.methods.name().call()
)
return { token0Contract, token1Contract, token0, token1 }
}
main()
I want to automate my staking on The Sandbox. For that I need in the first step to interact with the mSand-Matic Pool Contract. It is this one: https://polygonscan.com/address/0x4ab071c42c28c4858c4bac171f06b13586b20f30#code
I have written a little program in a GitHub repository to show what I have done: https://github.com/ChristianErdtmann/mSandMaticStakingAutomation
Or here is the code example from the contract-interact.js
Web3 = require('web3')
const fs = require('fs');
const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
mSandMaticContract.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780')
The ABI I have taken from the contract link on the top. But it seems there is a problem.
I tried for testing to read something from the contract. For that I used the function balanceOf(address), how you can see in the code.
But I always get this error:
TypeError: mSandMaticContract.balanceOf is not a function
I found the solution
web3 needs .methots to get acces to the balanceOf() function
if we want only to read so we need to add .call()
we need to add await before the function is called this needs to be in a asynchonus function
So the final working code is:
Web3 = require('web3')
const fs = require('fs');
const web3 = new Web3("https://polygon-rpc.com")
const contractAddress = "0x4AB071C42C28c4858C4BAc171F06b13586b20F30"
const contractJson = fs.readFileSync('./abi.json')
const abi = JSON.parse(contractJson)
const mSandMaticContract = new web3.eth.Contract(abi, contractAddress)
asyncCall()
async function asyncCall() {
console.log(await mSandMaticContract.methods.balanceOf('0x7e5475290Df8E66234A541483453B5503551C780').call())
}
If you dont want only to read you need addtional to sign the transaction with:
The solution is, to sign the transaction before sending we can doing this with any method by this code:
encoded = mSandMaticContract.methods.getReward().encodeABI()
var block = await web3.eth.getBlock("latest");
var gasLimit = Math.round(block.gasLimit / block.transactions.length);
var tx = {
gas: gasLimit,
to: publicKey,
data: encoded
}
web3.eth.accounts.signTransaction(tx, privateKey).then(signed => {
web3.eth.sendSignedTransaction(signed.rawTransaction).on('receipt', console.log)
})
I'm developing an AWS Lambda in TypeScript that uses Axios to get data from an API and that data will be filtered and be put into a dynamoDb.
The code looks as follows:
export {};
const axios = require("axios");
const AWS = require('aws-sdk');
exports.handler = async (event: any) => {
const shuttleDB = new AWS.DynamoDB.DocumentClient();
const startDate = "2021-08-16";
const endDate = "2021-08-16";
const startTime = "16:00:00";
const endTime = "17:00:00";
const response = await axios.post('URL', {
data:{
"von": startDate+"T"+startTime,
"bis": endDate+"T"+endTime
}}, {
headers: {
'x-rs-api-key': KEY
}
}
);
const params = response.data.data;
const putPromise = params.map(async(elem: object) => {
delete elem.feat1;
delete elem.feat2;
delete elem.feat3;
delete elem.feat4;
delete elem.feat5;
const paramsDynamoDB = {
TableName: String(process.env.TABLE_NAME),
Item: elem
}
shuttleDB.put(paramsDynamoDB).promise();
});
await Promise.all(putPromise);
};
This all works kind of fine. If the test button gets pushed the first time, everything seems fine and is working. E.g. I received all the console.logs during developing but the data is not put into the db.
With the second try it is the same output but the data is successfully put into the Db.
Any ideas regarding this issue? How can I solve this problem and have the data put into the Db after the first try?
Thanks in advance!
you need to return the promise from the db call -
return shuttleDB.put(paramsDynamoDB).promise();
also, Promise.all will complete early if any call fails (compared to Promise.allSettled), so it may be worth logging out any errors that may be happening too.
Better still, take a look at transactWrite - https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#transactWrite-property to ensure all or nothing gets written
I am using Bitcoin Cash JS to create a transaction, and my code is as follows:
let BITBOXCli = require('bitbox-cli/lib/bitbox-cli').default;
const explorers = require('bitcore-explorers')
const insight = new explorers.Insight('https://test-bch-insight.bitpay.com')
let BITBOX = new BITBOXCli();
let txb = new BITBOX.TransactionBuilder('testnet');
var To = 'mkiuwbSQQVxMvvbBcYEKUdZgJfURhu3hrW'
var from = 'mvStb7hPtDCL8dmyifPGcYTuToVzf7ajTb';
var bch = require('bitcoincashjs')
var bchLib = require('#owstack/bch-lib')
const buf = new Buffer('b27ab45d3e3d157e8b95f800347974f9991cf13ceb814e1992f40c5e4e6d5253', 'hex')
const privateKey = new bch.PrivateKey(buf, bch.Networks.testnet)
const address = privateKey.toAddress('testnet')
insight.getUnspentUtxos(address.toString(), function (error, utxos) {
if (error) {
console.error(error)
return
}
console.log(utxos)
const utxo = {
txid: utxos[0].txid,
outputIndex: utxos[0].vout,
script: utxos[0].scriptPubKey,
satoshis: utxos[0].satoshis
}
const transaction = new bch.Transaction()
.from(utxo)
.to(To, 50000)
.sign(0, privateKey)
console.log(transaction.toString())
});
Now when I am running this code, I am able to get the raw transaction hash but I am not able to broadcast transaction and message is as follows:
Missing Inputs Error:-25
Any idea about this error?
Or is there any other way to create BCH transaction?
It looks like you're trying to create a simple transaction to send BCH from one address to another. There is now an example for this exact use case in the BITBOX SDK repository:
https://github.com/Bitcoin-com/bitbox-javascript-sdk/blob/master/examples/applications/wallet/send-bch/send-bch.js
There are also other examples there like creating a wallet checking a balance:
https://github.com/Bitcoin-com/bitbox-javascript-sdk/tree/master/examples/applications/wallet
There are even more examples in the Wormhole SDK. (Wormhole SDK is a superset of BITBOX, so it can do anything BITBOX can do):
https://github.com/Bitcoin-com/wormhole-sdk/tree/master/examples