“Out of Gas” while transferring ethereum from account to contract - testing

I am using ganache to create 10 ethereum accounts. I want to transfer ethereum from one account to a smart contract. I am doing this by writing two following smart contracts in solidity;
pragma solidity >=0.4.0 <0.6.0;
contract Ether_Transfer_To{
function () external payable { //fallback function
}
function get_balance() public returns(uint){
return address(this).balance;
}
}
contract Ether_Transfer_From{
Ether_Transfer_To private the_instance;
constructor() public{
//the_instance=Ether_Transfer_To(address(this));
the_instance=new Ether_Transfer_To();
}
function get_balance() public returns(uint){
return address(this).balance;
}
function get_balance_of_instance() public returns(uint){
//return address(the_instance).balance;
return the_instance.get_balance();
}
function () external payable {
// msg.sender.send(msg.value)
address(the_instance).send(msg.value);
}
}
When I deploy the contract Ether_Transfer_From smart contract then I get its three-member functions as follows in remix;
But when I sent one 1 Wei from account to smart contract by writing 1 in the text box and clicking on a (fallback) button, then I get the following error;
transact to Ether_Transfer_From. (fallback) errored: VM Exception while
processing transaction: out of gas
I followed the answer of the same question by installing Ganache-cli 7.0.0 beta.0 by using following command;
npm install -g ganache-cli#7.0.0-beta.0
But I still get the same error. I think I am using older Ganache cli instead of Ganache-cli 7.0.0 beta.0 as it goes to C drive and I installed ganache 2.1.1 in D drive previously.
I just want to send ethereum from one account to other but I am really stuck in this out of gas Error. If there is any way to remove this error or transfer ethereum from one account to another then please let me know.

So this is what I did for one of my projects.
This snippet, deploys the compiles the solidity file and then deploys it and gets the address of the deployed contract address
const input = fs.readFileSync('Migrations.sol');
const output = solc.compile(input.toString(), 1);
const bytecode = output.contracts[':Migrations']['bytecode'];
const abi = JSON.parse(output.contracts[':Migrations'].interface);
var contract = new web3.eth.Contract(abi);
contract.deploy({
data: '0x'+bytecode,
})
.send({
from: chairPerson,
gas: 5500000,
gasPrice: '2000000000000'
})
.on('receipt', (receipt) => {
add=receipt.contractAddress;
})
Now using contract's abi, I can call methods of the deployed contract and use the following code to transfer '1.5' ether from one address to another.
contract.methods.registerRequest(fromAddress,toAddress,requestNumber).send({from:fromAddress,value : web3.utils.toWei('1.5', 'ether')}).on('transactionHash', (hashResult) => {-- some code--})
And also make the method in the solidity as payable to allow it to transfer ether, like :
function registerRequest(address requestedBy,address requestedTo,uint requestNumber) payable public{}
Refer : https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html#id12
Basically I used web3 api itself to transfer ether from one account
to another by calling my solidity method.
Also, check the following things :
1. While deploying, are you deploying with enough gas ? I faced this error when I was deploying the contract with less gas quantity
2. Your method in solidity should be payable

Related

How can I get metadata and my image to show up on OpenSea Testnet?

I followed along with Remix's beginner NFT course and successfully deployed a few NFTs using the Goerli testnet and their provided IPFS data. I uploaded my own image and metadata and can see it on IPFS but neither the metadata nor the image is populating on OpenSea.
Here is the code for the contract I am deploying:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts#4.4.0/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts#4.4.0/access/Ownable.sol";
contract Donation is ERC721, Ownable {
constructor() ERC721("Donation", "DONO") {}
function _baseURI() internal pure override returns (string memory) {
return "https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2";
}
function safeMint(address to, uint256 tokenId) public onlyOwner {
_safeMint(to, tokenId);
}
}
Please see the URL that I return for my metadata and subsequent link to my image. Is there anything you see that is immediately wrong that would indicate why nothing is populating (in the JSON file, code, or otherwise)?
For ERC721, the _baseURI will essentially be the base to be combined with the NFT's token id, so for example NFT with token ID 0 will have the tokenURI of:
https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2/0
which in this case after checking is invalid as https://ipfs.io/ipfs/QmXZKcU9WDZxvXvxoAL4YdZVR5Ssj97ayEYRPqYBHrRSb2 should be the valid tokenURI itself. OpenZeppelin designed the ERC721 contract this way as it is the most gas-efficient way to create a standard ERC721 NFT. However, the drawback is that it made it difficult to provide modified URI for each token ID.
If you like to set tokenURI with different base for different token ID, then you should instead check ERC721URIStorage in the contract wizard. This way, the ERC721 NFT contract will have the _setTokenURI(tokenId, uri) function, which allows you to modify the tokenURI for different token ID. However, keep in mind that this will be very expensive on the user side as string inputs cost a lot in EVMs.
Hope this helps~

How to Read Chainlink AggregatorV3Interface in Hardhat Deployment

Total beginner here apologies in advance.
I'm learning Solidity and using Hardhat and trying to figure out how to return the value of the Chainlink price feed in this tutorial contract after deployment. I know how to return the function output in remix but having trouble figuring out how to use console.log or another method in Hardhat. I am able to use console.log for built in functions like token address but can't figure out how to apply to other functions. This is using the Goerli Testnet btw.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract TestChainlink {
AggregatorV3Interface internal priceFeed;
constructor() {
// ETH / USD
priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e);
}
function getLatestPrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
// for ETH / USD price is scaled up by 10 ** 8
return price;
}
}
I tried emulating console.log usage that work for built in functions like token address to apply them to the Chainlink getLatestPrice() function.
const Token = await ethers.getContractFactory("TestChainlink");
const token = await Token.deploy();
console.log("Token address:", token.address);
i.e.
I tried a ton of different combinations this was the last one I will spare all the error messages since it probably isn't a complex solve for a non novice.
console.log("ETH Price:", getLatestPrice());
try
let price = await token.getLatestPrice();
console.log(`Eth price is: ${price}`);

Burning Deployed ERC Tokens In an NFT Mint Function - Compiles, but Transaction Fails

I am very new to Solidity, and have recently been working on trying to learn the ropes. For reference, I have been using code from this video (https://www.youtube.com/watch?v=tBMk1iZa85Y) as a primer after having gone through the basic crypto zombies tutorial series.
I have been attempting to adapt the Solidity contract code presented in this video (which I had functioning just fine!) to require a Burn of a specified amount of an ERC-20 token before minting an NFT as an exercise for myself. I thought I had what should be a valid implementation which compiled in Remix, and then deployed to Rinkeby. I call the allowAccess function in Remix after deploying to Rinkeby, and that succeeds. But, when I call the mint function with the two parameters, I get: "gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? execution reverted."
If I still send the transaction, metamask yields "Transaction xx failed! Transaction encountered an error.".
I'm positive it has to do with "require(paymentToken.transfer(burnwallet, amounttopay),"transfer Failed");", though I'm not sure what's wrong. Below is my entire contract code. I'm currently just interacting with the Chainlink contract on Rinkeby as my example, since they have a convenient token faucet.
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";
contract myNFTwithBurn is ERC721, Ownable {
address externalTokenAddress = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709; //Token Type to burn on minting
uint256 amounttopay = 5; //number of these tokens to burn
IERC20 paymentToken = IERC20(externalTokenAddress); //my code: create an interface of the external token
address burnwallet = 0x000000000000000000000000000000000000dEaD; //burn wallet
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
using Strings for uint256;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURIextended;
constructor() ERC721("NFTsWithBurn","NWB") {
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
function allowAccess() public
{
paymentToken.approve(address(this), 5000000); //This is my attempt to allow the contract access to the user's external tokens, in this case Chainlink (paymentToken)
}
function mintItem(address to, string memory tokenURI)
public
onlyOwner
returns (uint256)
{
require(paymentToken.transfer(burnwallet, amounttopay),"transfer Failed"); //Try to transfer 5 chainlink to the burn wallet
_tokenIds.increment();
uint256 id = _tokenIds.current();
_mint(to, id);
_setTokenURI(id, tokenURI);
return id;
}
}
If anybody can at least point me to what I'm doing completely wrong in the code that I've added, please do! TIA!
I'm not sure why are you trying to burn link in order to mint and nft but first check if the link code does not have a require that check if the destination address is the burn address if it has then burn the link is not possible and you should use any other erc20 maybe your own erc20, also your contract probably does not have any link and if you want to transfer the link from the user you should do this in the contract paymentToken.transferFrom(msg.sender,destinationAddress,amount) and if the user previously approve your contract you will able to send the tokens, and i suppose that the purpose of the allowAccess function is to make the user approve the contract to move the tokens that will never work, the approve function let's anyone that call it approve any address to move an amount of tokens, the thing is that to know who is approving to let other to move the tokens the function use msg.sender to explain how this work take a look at this example
let's say that your contract is the contract A and the link contract is the contract B
now a user call allowAccess in the contract A, so here the msg.sender is the user because they call the function
now internally this function call approve on contract B, here the contract A is the msg.sender, because the contract is who call the function
so what allowAccess is really doing is making the contract approving itself to move their own tokens that I assume it doesn't have

Solidity 'out of gas' exception when trying to transfer Ether

I try to transfer Ether from the contract to an address but it gives the error that the transaction is out of gas. I think it's a small problem but I can't find it. I have to specifically use solidity version 0.4.24.
The warning from Remix
The error from MetaMask
I have tried different methods, like:
address.transfer(amount);
address.send(amount);
address.call.value(amount)( );
All methods will give the same out of gas exception. and the send and call method will also give a warning that it's outdated and that I should use the transfer method.
I also tried to adjust the gas and it didn't work, I also tried the needed 2,300 for the transfer listed on the docs.
The code:
pragma solidity ^0.4.24;
contract TestContract {
function payAddress(address _address) external payable {
_address.transfer(msg.value);
}
}
If the problem is that the contract doesn't have any Ether to transfer, can it use the Ether I send with the function call? Or is the problem something else?
Thank you for reading.
edit:
I have tried to send Ether to my Contract and that works, I do have Ether on my contract now, but the function still gives the same error as before. So the problem is something else.
Current code:
pragma solidity ^0.4.24;
contract TestContract {
function() external payable { }
function payContract() public payable {}
function paySomeone(address _address, uint256 _amount) external {
_address.transfer(_amount);
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
The balance of the contract
The parameters I use
Same MetaMask error as before
As you can see here the balance of the contract is 10 wei, but when i try to send 9 wei it still gives the same out of gas error. I also still get the same error from Remix as before.
I also post the issue on the Stack exchange and got an answer there. The issue was my
Ganache version. I switched to the Robsten test network and it worked. I'll link the post here.
Yes. In order to send ether from contract to another address, first you must send some ether to the contract address. Take a look at this and this.

Truffle console send ETH to smartContract

I want to send some ETH to smart contract address
Test.deployed().then(function(instance) {return instance.contribute("0x1e0c326f4f24b5e9f5d42d695f48983d0a72b240", {from:web3.eth.accounts[0],value:10});})
but I always get
truffle(development)> Test.deployed().then(function(instance) {return instance.contribute("0x1e0c326f4f24b5e9f5d42d695f48983d0a72b240", {from:web3.eth.accounts[0],value:10});})
TypeError: instance.contribute is not a function
at evalmachine.<anonymous>:1:61
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
truffle(development)> truffle(development)>
I am using last version of truffle, so version 4.x
Same problem with
Test.deployed().then(function(instance) {return instance.getElements.call();})
Updated
contract MyContract Common {
function setMultisigWallet(address newMultisigWallet) public onlyOwner {
multisigWallet = newMultisigWallet;
}
function() external payable {
executeSale();
}
}
Send a transaction directly to a contract via instance.sendTransaction(). This is promisified like all available contract instance functions, and has the same API as web3.eth.sendTransaction but without the callback. The to value will be automatically filled in for you if not specified.