Connecting with a Blockchain node using Web3.js - javascript

Every time I connect to a blockchain I use the following lines of code, "let web3 = new Web3(new Web3.providers.HttpProvider("Address"). I understand the use of the address and the Providers to connect with a blockchain. But what is the use of the first part? "let web3 = new Web3(new Web3."
It successfully helps me to connect with a blockchain, but I don't understand the logic behind it.

let me ask your question.
So basically, the purpose of this code let web3 = new Web3(new Web3. is to create an object based on a Web3 object that was created using JavaScript and saved to the variable named web3.
After that, you can use all Web3 functions inside Web3 objects, such as getting the providers using your address.
The provider is an interface that Web3 uses to communicate with the Ethereum network. In this case, the provider is an HTTP provider, which means that the Web3 object will use HTTP to communicate with an Ethereum node at the specified "Address".
And other words, when you create a Web3 object with an HTTP provider, you are essential setting up a connection to an Ethereum node running on a remote server. This allows you to send requests to the Ethereum network, such as querying for account balances, sending transactions, or interacting with smart contracts.

Related

What does hardhat "deployed()" do?

I have the below code
const SimpleStorageFactory = await ethers.getContractFactory(
"SimpleStorage"
)
const simpleStorage = await SimpleStorageFactory.deploy()
await simpleStorage.deployed()
await simpleStorage.deployTransaction.wait(6)
I understand that hardhat's getContractFactory is automatically supplied the abi, binary and specified private key for signing transactions. After this is done I am assuming that SimpleStorageFactory.deploy() is the same as in ethers and deploys the contract to the blockchain, and then I am waiting 6 network confirmations. However, I am confused why hardhat has await simpleStorage.deployed() and what this does?
I have tried reading the documentation on hardhat but have not found an answer to this.
The await simpleStorage.deployed() line of code is waiting for the SimpleStorage contract to be deployed to the Ethereum network. When a contract is deployed, it is uploaded to the network and made available for interaction.
The deployed() method is a Promise that returns a ContractReceipt object, which contains information about the deployment transaction, such as the transaction hash, block number, and contract address.
This method is useful because it allows you to ensure that the contract has been deployed and is available for interaction before you try to call any of its methods or access its state. Without this line, the rest of the code might execute before the contract is fully deployed, which could result in errors.
The await simpleStorage.deployTransaction.wait(6) line of code is waiting for the deployment transaction to be included in six blocks on the Ethereum blockchain. This is done to ensure that the transaction has sufficient confirmations, which helps to ensure the transaction will not be reversed.
This hardhat plugin adds a mechanism to deploy contracts to any network, keeping track of them and replicating the same environment for testing.

Web3 contract.methods.approve(contractAddress, value), how to prompt user to approve using test account address?

I am able to call Smart contract methods from client machine in development env:
example:
contract.methods.allowance
contract.methods.approve
and I can see the transactions in Ganache UI returned from contract.methods.approve
Which is fine. However, what I am expecting to see in the browser is a prompt in the connected wallet to approve the transaction, similar to the prompt I get when calling:
window.ethereum.request({ method: 'eth_requestAccounts' });
or
window.ethereum.request({ method: 'eth_sendTransaction', params});
The account I am using is one I used provided by Ganache UI where I imported the private key into metamask.
I must be misunderstanding something because there is no point in an "approve" feature conceptually if there is no "approving" taking place by the owner of the address apart from the client machine calling "approve". Does this have something to do with the fact the the dev env already knows what the private key is?
When switching metamask account to an account outside of the development network (my actual account), I get "sender account not recognized" error. But why isn't default behaviour to ask the unrecognised account to approve the transaction?
example, I can call: window.ethereum.request({ method: 'eth_sendTransaction', params}); with the "unrecognised" account and approve the transaction but I can't make a SC call and approve it with this account.
To answer my own question the answer is:
Use metamask "window.ethereum" as a provider allowing it to select the network instead of injecting the RPC directly.
I also switched to ethersjs and stopped using web3js. So the following:
const provider = new ethers.providers.Web3Provider(window.ethereum, "any");
Instead of injecting an http provider since the the network doesn't have you private key.

Web3js event listen / subscribe to transactions to or from a wallet address

So I am connecting to Binance Smart Chain RPC websocket from Moralis.io. And trying to listen to wallet amount changes of a certain wallet address.
What I want to do is, I want to trigger a event whenever there is a transfer from or to this wallet address. I understand how to do it with BEP20 tokens but I require a solution to monitor the wallet address for BNB transfers.
The code that I put together:
const web3 = new Web3(new Web3.providers.WebsocketProvider('URI'))
let options = {
address: '0xe....'
}
const subscribe = web3.eth.subscribe('logs', options, (err, res) => {})
subscribe.on('data', (txLog) => console.log(txLog))
This doesn't work when I send a certain amount of BNB to this account.
I went through the documentation of web3js but couldn't figure out.
I found a longer way around for this problem where someone suggests to listen to all pending transactions and try to get the transaction data of each of these transactions and evaluate if any of these are from or to the wallet address. But I think it is an extremely ineffective and inefficient way to do it as it requires someone to run their own node to do it in a meaningful way.
listen to all pending transactions and try to get the transaction data of each of these transactions
I agree that this is an ineffective way. But with the current state of the JSON-RPC API, it's still the most effective way available. Apart from using a 3rd party service that does all this work in the background and provides the data over their custom API.
Note: The link goes to Ethereum documentation, but Binance Smart Chain implements the same JSON-RPC API.
There's simply no method to subscribe to or poll incoming native transactions to a specified address.
And since web3, ethers.js, and many other libraries are wrappers of this API, they can only support methods that the API supports.

Firebase Storage emulator does't support getSignedUrl

I have the line
onst [url] = await blob.getSignedUrl({ action: 'read', expires: Date.now() + 60 * 1000, contentType: mimetype })
When I run my unit-tests with the Firebase storage emulator I got the error:
Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information
How can I use getSignedUrl with Firebase emulator?
When using a blob signed url, use service account credentials instead of the default ADC. Having been said that, you have two options:
You can create a service account that will use the command using the Cloud SDK: gcloud iam service-accounts keys create FILE_NAME.json --iam-account=NAME#PROJECT_ID.iam.gserviceaccount.com; which you can use to call Firebase server APIs from your app server or trusted environment. After creating your service account, you must initialize with a service account key file.
Here's an example java code for initializing:
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
You can also check the Firebase Service Accounts to help you identify which service account you will use in your project.
Another option is to set the service account key in an environment variables.
For Linux or macOS:
export GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"
Example is:
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
For Windows (using powershell):
$env:GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"
Example is:
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
Just note that this variable only applies to your current shell session, so if you open a new session, set the variable again.
Update:
In Google Cloud Platform environments, such as Cloud Functions and App Engine, you usually don't provide a keyFilename or credentials during instantiation. In those environments, we call the signBlob API to create a signed URL. As was stated here. In that case, the service account used must have Service Account Token Creator Role.
The Service Account Token Creator Role enables impersonation of service accounts to create OAuth2 access tokens, sign blobs, or sign JWTs. Provide your service account when initializing the client. If using default credentials, then make sure that the Cloud Functions service account must have Service Account Token Creator Role, as it is required when calling the signBlob API if the app is deployed within GCP.
You can further check this github issues comment.

Cannot create database with pouchdb in couchdb

while trying to just create a database with pouchDB for couchDB, the following error is thrown:
{"error":"not_found","reason":"Database does not exist."}.
My code to create a test db is as simple as this:
var db = new PouchDB('http://localhost:5984/testdb');
Also, the couchDB server is running and reachable at http://localhost:5984/ and it says:
{"couchdb":"Welcome","version":"2.1.1","features":["scheduler"],"vendor":{"name":"The Apache Software Foundation"}}
I have even enabled CORS for couchDB.
Thanks in advance.
According to the PouchDB API (especially the info block), it doesn't automatically create the database by creating a new PouchDB object.
You need to call an API function of the database in order to create the database.
For example, you could create your PouchDB object and then call db.info() to create the database.

Categories

Resources