In following code:
console.log("Deploying contract....");
const simpleStorage = await simpleStorageFactory.deploy();
await simpleStorage.deployed();
Line 2 deploys the contract and we get hold of it.
Why do we need to call deployed method in Line3?
calling deploy() will create the transaction, and you can get the contract address immediately, however this does not mean the transaction has been processed and included within a block.
deployed() will wait until it has been. Under the hood it will poll the blockchain until the contract has been succesfully processed. See: https://github.com/ethers-io/ethers.js/blob/master/packages/contracts/src.ts/index.ts#L824
I don't think you technically have to call deployed(), but if you need to do anything after the contract has been deployed and need to make sure it has been included in a mined block, then waiting for deployed() is advised.
Related
I am trying to detect timestamp in Ethereum node but there are no methods/functions.
How do we find this?
I am getting swap logs and parsing them but couldn't find direct way to detect contract creation date.
Contract creation date is not available using a direct method.
Blockchain explorers usually collect it the following way:
They scan every transaction on every block on the chain
If the transaction receipt contains non-null contractAddress property, it means that this transaction deployed a contract.
Time of the transaction (and effectively time of the contract deployment) is available as part of the block in which the tx was produced
This is quite complicated. There is no method to get the Transaction that deployed the Contract.
First of all, there are multiple ways to deploy a contract:
Via the Deployment Transaction, here you will get the contractAddress in the tx receipt.
Via another contract, with create2/create method. For example in this way Uniswap: Factory Contract creates Pair contracts. And there is no API in RPC to find out this type of deployment. You need a node that can return such "Internal Calls".
There are some workarounds. In your case, do you just need the timestamp? Then you have just to find the block when the contract was deployed.
The archive node.
Use binary search to find the block number, when eth_getCode returns not the empty data, and the previous one is empty.
Get the timestamp of the block.
If you need the transaction:
Use the previous method to find the block
Load transactions and their receipts.
Search for a Deployment Transaction, which has your contractAddress in the receipt.
If not found, almost always the contract emits an Event when creating another contract. So look into the address, data and topics to match your contract address of every log entry.
Not a universal workaround: if you know the Event which gets emitted in the constructor or by the parent's contract, you can search for it with getPastLogs.
You can use the 3rd party API, like https://docs.etherscan.io/api-endpoints/contracts to get the Get Contract Creator and Creation Tx Hash. After that:
Get the blockNumber from transaction fetched by txHash.
Get the timestamp from block fetched by blockNumber.
I am trying to implement this Airdrop: https://github.com/odemio/airdropper/blob/master/Airdropper.sol
Initially, I started writing tests for our use-case, but the airdrop was not working.
function airdrop(address source, address[] dests, uint[] values) public onlyOwner {
// This simple validation will catch most mistakes without consuming
// too much gas.
require(dests.length == values.length);
for (uint256 i = 0; i < dests.length; i++) {
require(token.transferFrom(source, dests[i], values[i].mul(multiplier)));
}
}
Then I moved to Remix to goe through the whole airdrop process, including our Contract deployment, token minting and allowance.
In Remix debugger I found out that the issue is on the line
require(token.transferFrom(source, dests[i], values[i].mul(multiplier)));
I also tested the transferFrom function directly on our contract using the same values on Remix.
The error I get when trying to airdrop is:
transact to Airdrop.airdrop errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information.
What could cause this issue and how can I debug this further? :)
Thanks and have a nice day!
The error could be for several reasons:
source doesn’t have enough tokens to cover all of the transfers.
One or more destination addresses are invalid.
The approve wasn’t done correctly (it’s the airdrop contract that needs to be approved, not the initiator of the transaction).
You can narrow it down by removing the require and see if any drops are successful (the way you have it coded, one failure will roll back the entire transaction).
When we call a solidity function via web3js, how does the code flows along with data formats during all the process?
For example, if I call a solidity function through web3js, how does it get executed. Can anyone explain the complete flow?
First of all, I recommend taking the time to read How does Ethereum work, anyway?
But for now, a short explanation
When you call a method on a contract through web3.js, the library
will encode your method call as data attribute on the transaction.
Here's a good explanation about ethereum transactions and data
attribute
The ethereum node your web3.js is connected to will receive your transactions and do some basic checks of nonce and balance
Once the basic checks pass, the node will broadcast the transaction to the rest of the network
When a network node receives a transaction with data attribute, it will execute the transaction using the Ethereum EVM. The outcome
of the transaction is modified state of the contract storage. More
about contract storage
The expectation is that the transaction will produce the same state change on every single node in the network. This is how
consensus is reached and the transaction (and the contract state
change) become part of the canonical chain (mined and not belonging
to an uncle block)
I'm trying to deploy the following contract on Ropsten using an injected web3 environment (i.e. metamask) on remix.ethereum.org/
pragma solidity ^0.4.16;
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping (address => uint) public balances;
// Events allow light clients to react on
// changes efficiently.
event Sent(address from, address to, uint amount);
// This is the constructor whose code is
// run only when the contract is created.
function Coin() public {
minter = msg.sender;
}
}
I've been able to create contracts with ease using remix before. I'm not sure what has changed, but I can't create contracts at all because of the gas limit thing. I've even gone as far as setting the gas limit to 2 full Ethers (i.e. value 1 ether with max of 2). I have close to 3 ethers in my metamask wallet. The remix "Account" dropdown also displays my metamask address correctly so it seems that the injected environment is connected.
When I try to create this contract I can't get past the gas required exceeds limit 2 error. I'm scratching my head as to why this simple contract would exceed the cost of 2 full Ethers.
Other parameters for remix in use:
optimize=false&version=soljson-v0.4.20+commit.3155dd80.js
Is there a setting on remix that I've forgotten? I'm Trying to deploy this from Chrome.
edit: I'm still scratching my head on this one. I was able to create the contract above for a brief moment after refreshing my page, but I came in today to try and run the code from https://www.ethereum.org/token and I can't get past the exceeds gas error with a value of 20 Gwei and a limit of 3000000. Note, I tried using the simple sample contract above and I'm back to where I was when I started - even the simple "Coin" contract above apparently exceeds the gas limit.
edit 2: Well, I think I'm getting somewhere. I've changed the compiler version from "soljson-v0.4.20+commit.3155dd80.js" to "soljson-v0.4.19+commit.c4cbbb05.js". Then I refresh the page 3 times. After that I wait a couple of minutes and things seem to be working again. There is something else happening here because when I reject the transaction in metamask and then return to remix to create again, I encounter the gas exceeded error. I don't believe the issue here is metamask as I've tried to connect locally using testrpc - localhost:8545 - and experience the same issue. All I can say is that the same code that I try to create fails to submit because of the gas error most of the time but occasionally works regardless of compiler version.
I am using testrpc and truffle to test my smart contract before deploying it to the real network.
In my contract, each node has to register in the contract by calling the function register, after that he can send or receive messages to/from contract( the blockchain )
The problem is, when an address ( let say account 1 from testrpc accounts) call the functions (send or receive ) the transaction doesn't occur and this message appears
VM Exception while processing transaction: invalid JUMP at
But when I use another unregistered account to call this function, it works.
Although no messages have been sent or received but no exceptions..
Any idea how I can solve this.
Thanks
Unless your using an old version of solc to compile your solidity the chance of this being an optimization problem is almost none.
Now, what does this mean then, it can happen when for example you run a modifier and it doesn't work. or if you try to call a function you are not allowed to and it throws. For example, it happens a lot after an ICO finishes and you try to use a function that can't be used anymore due to a date constraint it returns an Invalid Jump
I can't see your code but I think you might have reversed your if condition in your modifier and now it returns true if the user is not registered.