Why are all ethersjs & web3js calls to BSC network failing? - node.js

All calls using "wss://bsc-ws-node.nariox.org:443" and other RPC/WSS endpoints have been failing throughout this week. It just hangs and doesn’t return anything.
This is happening in BSC network, but is okay in Polygon network.
On BSC network it happens with both Ethers.js and Web3.js libraries.
Below is a sample implementation using ethers.js
Note that this has been tested from a NodeJS server on an AWS server located in London. Then subsequently it was tested on a Moralis server based in Singapore, but obtained the same results (hanging & no return).
code:
const ethers = require('ethers');
console.log(`ethers version: ${ ethers.version }`);//5.4.4
const Web3 = require('web3');
const _ = require('lodash');
const dotenv = require("dotenv");
dotenv.config();
//const add = “ wss://ws-matic-mainnet.chainstacklabs.com/”; //“https://polygon-rpc.com”; //polygon // swing 1
const add = "wss://bsc-ws-node.nariox.org:443"; //bsc
console.log(`add: ${ add }`);
const mnemonic_3 = process.env.YOUR_MNEMONIC_3 //''; //privatekey GANTI // add own private key to test
const provider = new ethers.providers.WebSocketProvider( add );
const wallet_3 = new ethers.Wallet(mnemonic_3);
const account_3 = wallet_3.connect(provider);
let awaits = async () => {
console.log(`account: ${ await account_3.getAddress() }`);
console.log(`wallet: ${ await wallet_3.getAddress() }`);
//console.log(`account: ${ await account_3.provider.getSigner().getAddress() }`);
console.log(`signer: ${ account_3 == (await account_3.provider.getSigner()) }`);
console.log(`signer: ${ wallet_3 == (await account_3.provider.getSigner()) }`);
//console.log(`provider: ${ await account_3.provider.getAddress() }`); // not a function
// A Human-Readable ABI; for interacting with the contract, we
// must include any fragment we wish to use
const abi = [
// Read-Only Functions
"function balanceOf(address owner) view returns (uint256)",
"function decimals() view returns (uint8)",
"function symbol() view returns (string)",
// Authenticated Functions
"function transfer(address to, uint amount) returns (bool)",
// Events
"event Transfer(address indexed from, address indexed to, uint amount)"
];
// This can be an address or an ENS name
//const address = "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270"; // matic - polygon // swing 2
const address = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; // bnb - bsc
// Read-Only; By connecting to a Provider, allows:
// - Any constant function
// - Querying Filters
// - Populating Unsigned Transactions for non-constant methods
// - Estimating Gas for non-constant (as an anonymous sender)
// - Static Calling non-constant methods (as anonymous sender)
const erc20 = new ethers.Contract(address, abi, provider);
console.log(`decimals: ${ await erc20.decimals() }`);
// Read-Write; By connecting to a Signer, allows:
// - Everything from Read-Only (except as Signer, not anonymous)
// - Sending transactions for non-constant functions
const erc20_rw = new ethers.Contract(address, abi, account_3)
console.log(`decimals: ${ await erc20_rw.decimals() }`);
}
awaits();

I changed provider to Chainstack, works great now.
Steps to sign up are outlined here

Related

Getting error "Transaction Oversize" while creating a smart contract in Hedera blockchain

My bin file size is 18kb only. I also get a solution to use IPFS but don't know how to use it. If there is any reference for using IPFS then share me plz. :
Error: PrecheckStatusError: transaction 0.0.34898094#1653658245.135892060 failed precheck with status TRANSACTION_OVERSIZE
Here is my code :
const {
AccountId,
PrivateKey,
Client,
FileCreateTransaction,
ContractCreateTransaction,
ContractFunctionParameters,
ContractExecuteTransaction,
ContractCallQuery,
Hbar
} = require("#hashgraph/sdk");
const fs = require("fs");
const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromString(process.env.OPERATOR_PVKEY);
const client = Client.forTestnet().setOperator(operatorId, operatorKey);
async function main() {
// Import the compiled contract bytecode
const contractBytecode = fs.readFileSync("first_contract_sol_ABC_TOKEN.bin");
// Create a file on Hedera and store the bytecode
const fileCreateTx = new FileCreateTransaction().setContents(contractBytecode).setKeys([operatorKey]).setMaxTransactionFee(new Hbar(1))
.freezeWith(client);
const fileCreateSign = await fileCreateTx.sign(operatorKey);
console.log(Date.now() / 1000);
const fileCreateSubmit = await fileCreateSign.execute(client);
const fileCreateRx = await fileCreateSubmit.getReceipt(client);
const bytecodeFileId = fileCreateRx.fileId;
console.log(`- The bytecode file ID is: ${bytecodeFileId} \n`);
// Instantiate the smart contract
const contractInstantiateTx = new ContractCreateTransaction()
.setBytecodeFileId(bytecodeFileId)
.setGas(100000)
.setConstructorParameters(
new ContractFunctionParameters().addString("Alice").addUint256(111111)
);
const contractInstantiateSubmit = await contractInstantiateTx.execute(client);
const contractInstantiateRx = await contractInstantiateSubmit.getReceipt(
client
);
const contractId = contractInstantiateRx.contractId;
const contractAddress = contractId.toSolidityAddress();
console.log(`- The smart contract ID is: ${contractId} \n`);
console.log(`- Smart contract ID in Solidity format: ${contractAddress} \n`);
}
main();
You are hitting the TRANSACTION_OVERSIZE error because Hedera transactions have a 6kb size limit including all signatures.
If the compiled bytecode for your contract is relatively large, then you will need to create a file on Hedera, then append the contents in multiple chunks, and then create the contract.
The SDK now handles those 3 steps for you when you use ContractCreateFlow().Here's an example:
const contractCreate = new ContractCreateFlow()
.setGas(100000)
.setBytecode(bytecode);
//Sign the transaction with the client operator key and submit to a Hedera network
const txResponse = contractCreate.execute(client);
//Get the receipt of the transaction
const receipt = (await txResponse).getReceipt(client);

Transfer NFT using Token.createTransferInstruction

We have a transaction that transfers SOL & an NFT from the wallet's owner to our wallet.
The transaction contains simple instructions:
Token.createAssociatedTokenAccountInstruction
Conditionnal, depending on the destination (our wallet)
Token.createTransferInstruction
Transfers from the owner's token account to our token account.
SystemProgram.transfer
SOL transfer.
Here is the transfer code (spl-token v0.1.8)
let createTransferInstructions = async function (mint, from, to, cluster) {
let connection = new Connection(cluster, "confirmed")
const mintPublicKey = new PublicKey(mint);
const ownerPublicKey = new PublicKey(from);
const destPublicKey = new PublicKey(to);
// GET SOURCE ASSOCIATED ACCOUNT
const associatedSourceTokenAddr = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
ownerPublicKey
);
// GET DESTINATION ASSOCIATED ACCOUNT
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
const instructions = [];
if (receiverAccount === null)
instructions.push(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
ownerPublicKey
)
)
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
associatedSourceTokenAddr,
associatedDestinationTokenAddr,
ownerPublicKey,
[],
1
)
);
return instructions;
}
Here is the transaction code:
var transaction = new this.solana.Transaction({
feePayer: new this.solana.PublicKey(from),
recentBlockhash: await blockhashObj.blockhash
});
for (let transferInstruction of transferInstructions) {
transaction.add(transferInstruction);
}
transaction.add(this.solana.SystemProgram.transfer({
fromPubkey: new this.solana.PublicKey(this.provider.publicKey),
toPubkey: new this.solana.PublicKey(farm.address),
lamports: 10000000
}));
The owners have to validate the transaction with their wallets (phantom, solflare etc..)
And everything works great, for most NFTs.
Some NFT owners are complaining about not being able to validate the transaction on the wallet, an error message indicates that the transaction can't be confirmed.
However, the NFT can be transferred successfully using the wallet's interface, can be listed on marketplaces etc. Even when the NFT is transferred to another wallet, the transaction above works perfectly.
I'm wondering if this has anything to do with the associated token account?
If so, what is the solution?

fulfillOrder Opensea-js function returning undefined transaction hash

I'm trying to purchase a fixed price listed NFT from a specific collection using the opensea-js sdk, however when passing through a valid order into seaport.fulfillOrder() I am just getting undefined as the returned value.
My assumption is that the web3 provider is incorrectly set up for the account looking to make the purchase but I have been stuck on this for hours and haven't made any progress. Anyone had any luck using this method to successfully purchase NFTs on Opensea through Node.js?
I'm testing on the Rinkeby testnet.
Here's the code I use to fulfill the order, the order object is valid and retrieved using seaport.api.getOrder()
const order = await seaport.api.getOrder({
asset_contract_address: NFT_CONTRACT_ADDRESS,
maker: undefined,
taker: '0x0000000000000000000000000000000000000000',
owner: undefined,
side: OrderSide.OrderSide.Sell,
bundled: false,
token_id: token_id,
sale_kind: 0
});
const accountAddress = '0x12....';
const transactionHash = await seaport.fulfillOrder({
accountAddress,
order,
}).catch(err => console.log(err));
console.log("tx hash: " + transactionHash);
Here's the code I'm using to initialise web3 and seaport:
const provider = new Web3.providers.HttpProvider(walletAPIUrl);
const web3 = new Web3(provider);
const account = web3.eth.accounts.privateKeyToAccount('0x' + PRIVATE_KEY);
web3.eth.accounts.wallet.add(account);
web3.eth.defaultAccount = account.address;
const seaport = new OpenSeaPort(
provider,
{
networkName: Network.Rinkeby,
},
(arg) => console.log(arg)
);
Below is the error message I'm seeing when running the function:

Polygon transaction working just fine on Mumbai but not on Mainnet

Hello I'm trying to mint an NFT using Polygon and it works just fine on Mumbai but as soon as i switch over to the mainnet the transaction doesn't go through instead of going through in 5 seconds on mumbai. Even though im using the exact same contract just deployed on the mainnet instead of Mumbai and the code is the same too. All im doing is switching the contract address and rpc url but for some reason it just doesn't work on the Polygon mainnet below is the code im using.
// Init contract
const contractABI = require('../../contract-abi.json');
const contractAddress = config.mintingContractAddress;
const contract = await new this.web3.eth.Contract(contractABI, contractAddress);
// Mint NFT
const nft = contract.methods.mintNFT(user.walletAddress, metadataUploadURL, user.paymentAddress).encodeABI();
// Get gas pricing
const priorityFees = await axios.get('https://gasstation-mainnet.matic.network');
const estBaseGas = await this.web3.eth.estimateGas({
data: nft,
to: contractAddress,
});
console.log('USING GAS: ' + estBaseGas);
// Sign NFT minting transaction
const totalGas = estBaseGas + priorityFees.data.standard;
console.log('TOTALGAS: ', Math.round(totalGas).toString());
const transaction = await this.web3.eth.accounts.signTransaction(
{
from: user.walletAddress,
to: contractAddress,
nonce: await this.web3.eth.getTransactionCount(user.walletAddress, 'pending'), // Get count of all transactions sent to the contract from this address including pending ones
data: nft,
// maxPriorityFee: priorityFees.data.average, Not supported on Polygon MATIC yet
gas: Math.round(totalGas).toString(),
gasPrice: await this.web3.eth.getGasPrice(),
},
wallet.privateKey,
);
this.logger.silly('Finished signing NFT transaction');
// Send the transaction that we signed
const mintT = await this.web3.eth.sendSignedTransaction(transaction.rawTransaction);
this.logger.silly('Sent transaction');
console.log(mintT);
Also tried this for signing
// Get gas pricing
const priorityFees = await axios.get('https://gasstation-mainnet.matic.network');
const estBaseGas = await this.web3.eth.estimateGas({
data: nft,
to: contractAddress,
});
console.log('USING GAS: ' + estBaseGas);
// Sign NFT minting transaction
const totalGas = estBaseGas + priorityFees.data.standard;
console.log('TOTALGAS: ', Math.round(totalGas).toString());
console.log('P', priorityFees.data.standard);
const gp = this.web3.utils.toWei(priorityFees.data.standard.toString(), 'Gwei').toString();
console.log('GP', gp);
const transaction = await this.web3.eth.accounts.signTransaction(
{
from: user.walletAddress,
to: contractAddress,
nonce: await this.web3.eth.getTransactionCount(user.walletAddress, 'pending'), // Get count of all transactions sent to the contract from this address including pending ones
data: nft,
// maxPriorityFee: priorityFees.data.average, Not supported on Polygon MATIC yet
gas: '1000000',
gasPrice: gp,
},
wallet.privateKey,
);
Mempool explorer for transaction that takes forever and nearly instant one.
Forever:
Instant:
One on mainnet that used 30 gwei of gas:
Does anybody know why this is happening?
Also yes i do know that the fast one does have 2 extra gwei in gas but even setting it to that manually it still takes forever and according to https://polygonscan.com/gastracker even with one gwei it should be processed within 30 seconds. Even when using 50 Gwei it seems to take hours to process or maybe it's being dropped? The transactions don't even seem to be getting to the contract they are just stuck somewhere in the chain.
contract address: 0xa915E82285e6F82eD10b0579511F48fD716a2043
contract source code:
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract MyNFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
event MintedNFT(address recipent,string tokenURI,address artist, uint256 tokenID);
mapping(uint256 => address) private artists; // Used to store token ids => artist addresses
// mapping(uint256 => uint256) private royalties; // tokenId => royaltyPercentage
// mapping(uint256 => address) private nftMintInitators; // Used to store token ids => sender addresses
// mapping(uint256 => bool) private royaltiesSet;
constructor(string memory name_, string memory symbol_)
ERC721(name_, symbol_) {
}
// // Support for https://eips.ethereum.org/EIPS/eip-2981
// /// #notice Called with the sale price to determine how much royalty
// // is owed and to whom.
// /// #param _tokenId - the NFT asset queried for royalty information
// /// #param _salePrice - the sale price of the NFT asset specified by _tokenId
// /// #return receiver - address of who should be sent the royalty payment
// /// #return royaltyAmount - the royalty payment amount for _salePrice
// function royaltyInfo(
// uint256 _tokenId,
// uint256 _salePrice
// ) external view returns (
// address receiver,
// uint256 royaltyAmount
// ) {
// return (
// artists[_tokenId],
// _salePrice * royalties[_tokenId] // Take percentage
// );
// }
// function updateRoyaltyPercentage(
// uint256 royaltyPercentage, // In decimal like 0.5 or 0.25 (Send 0.0 for no royalties)
// uint256 tokenID
// ) public {
// if (msg.sender == nftMintInitators[tokenID] && royaltiesSet[tokenID] == false) {
// royalties[tokenID] = royaltyPercentage;
// royaltiesSet[tokenID] = true;
// }
// }
function mintNFT(address recipient,
string memory tokenURI,
address artist // Address for the artist not using _msgSender() because this transaction is sent by the users NFT holding account
)
public
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
artists[newItemId] = artist;
// nftMintInitators[newItemId] = msg.sender;
// royaltiesSet[newItemId] = false;
emit MintedNFT(recipient,tokenURI,artist,newItemId);
return newItemId;
}
}
You can test with simple code just to mint one NFT. Adding gasPrice and gasLimit parameters directly into minting function could help
const hre = require("hardhat");
async function main() {
const NFT = await hre.ethers.getContractFactory("NFTNAME");
const WALLET_ADDRESS = "0xxxxxxxxxxxxxx"
const CONTRACT_ADDRESS = "0xa915E82285e6F82eD10b0579511F48fD716a2043"
const contract = NFT.attach(CONTRACT_ADDRESS);
mintedNFT = await contract.mintNFT(WALLET_ADDRESS,{ gasLimit: 285000, gasPrice: ethers.utils.parseUnits('30', 'gwei')});
console.log("NFT minted:", mintedNFT);
}
main().then(() => process.exit(0)).catch(error => {
console.error(error);
process.exit(1);
});

How to get Smart Contract address when it is deployed with web3.js

I have tried to deploy a SmartContract from web3.js node library, I am getting a transaction hash from it but how would I get the contract address after It's been mined by a miner?
finally i got the answer
var Tx=require('ethereumjs-tx')
const Web3=require('web3')
const web3 = new Web3('https://rinkeby.infura.io/xxxxxxxxxxxxxxxxxx')
const account1='0xf2b6xxxxxxxxxxxxxxxxxxx83e9d52d934e5c'
const privateKey1=Buffer.from('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx','hex')
web3.eth.getTransactionCount(account1,(err,txCount)=>{
//smart contract data
const data = 'your data here'
//create transaction object
const txObject={
nonce:web3.utils.toHex(txCount),
gasLimit:web3.utils.toHex(1000000),
gasPrice:web3.utils.toHex(web3.utils.toWei('10','gwei')),
data: data
}
//sign the transaction
const tx = new Tx(txObject)
tx.sign(privateKey1)
const serializedTx = tx.serialize()
const raw='0x'+serializedTx.toString('hex')
//broadcast the transaction
web3.eth.sendSignedTransaction(raw,(err,txHash)=>{
console.log('err : ',err,'txHash : ',txHash)
//use this hash to find smartcontract on etherscan
}).on('receipt', console.log,);
})
.on() method wait till the end of block mining and returns the address of transaction(here contract address). This method is applicable if you don't want to use metamask to sign your transaction and broadcast to the network.
This returns the contract address...
MyContract is the .json file in the build/contracts folder that is created by migration.
const netId = await web3.eth.net.getId();
const deployedNetwork = MyContract.networks[netId];
const contract = new web3.eth.Contract(
MyContract.abi,
deployedNetwork.address
);
Add .address after the object.
var contact = web3.eth.contract.new(abi,{from: web3.eth.accounts[0], data: bc});
console.log(contract.address); // Prints address
If you just want to get the smart contract by transaction hash which deployed the smart contract, you can use the the web3.eth.getTransactionReceipt fetches the receipt for a transaction hash. The receipt has a contactAddress field filled in if the transaction was a deployment.
Check this out: https://github.com/ChainSafe/web3.js/issues/3515

Resources