Hi Im trying to create FlashLoan Sol File but when I try to run it locally it gives me ProviderError and when I try to run it on Remix It gives back gas estimation error this is the solidity code Im trying to run:
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.10;
import {FlashLoanSimpleReceiverBase} from "#aave/core-v3/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol";
import {IPoolAddressesProvider} from "#aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol";
import {IERC20} from "#aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol";
contract FlashLoan is FlashLoanSimpleReceiverBase {
address payable owner;
constructor(
address _addressProvider
) FlashLoanSimpleReceiverBase(IPoolAddressesProvider(_addressProvider)) {
owner = payable(msg.sender);
}
function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
) external override returns (bool) {
// at this point we already have borrowed funds
uint256 amountOwed = amount + premium;
IERC20(asset).approve(address(POOL), amountOwed);
return true;
}
function requestFlashLoan(address _token, uint256 _amount) public {
address receiverAddress = address(this);
address asset = _token;
uint256 amount = _amount;
bytes memory params = "";
uint16 referralCode = 0;
POOL.flashLoanSimple(
receiverAddress,
asset,
amount,
params,
referralCode
);
}
function getBalance(address _tokenAddress) external view returns (uint256) {
return IERC20(_tokenAddress).balanceOf(address(this));
}
function withdraw(address _tokenAddress) external onlyOwner {
IERC20 token = IERC20(_tokenAddress);
token.transfer(msg.sender, token.balanceOf(address(this)));
}
modifier onlyOwner() {
require(
msg.sender == owner,
"Only the contract owner can call this function!"
);
_;
}
receive() external payable {}
}
locally this is my setup
deployFlashLoan.js
const hre = require("hardhat");
async function main() {
const FlashLoan = await hre.ethers.getContractFactory("FlashLoan");
const flashLoan = await FlashLoan.deploy(
"0xa41E284482F9923E265832bE59627d91432da76C"
);
await flashLoan.deployed();
console.log("Flash loan contract deployed: ", flashLoan.address);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
hardhat.config.js:
require("#nomicfoundation/hardhat-toolbox");
require("dotenv").config();
/** #type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.10",
networks: {
goreli: {
url: process.env.INFURA_GORELI_ENDPOINT,
accounts: [process.env.PRIVATE_KEY],
},
},
};
.env :
PRIVATE_KEY="(My metamask private key here)"
INFURA_GORELI_ENDPOINT="https://celo-mainnet.infura.io/v3/(my api code here)"
Please if anyone has any idea can you help me ?
I am trying to connect web3js in the javascript section of my html to my ganache-cli nodejs server
ganache deployment script:
const ganache = require("ganache-cli");
const Web3 = require("web3");
const web3 = new Web3(ganache.provider());
const { interface, bytecode } = require("./compile");
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({
data: bytecode,
arguments: ["test"],
})
.send({ from: accounts[0], gas: "1000000" });
console.log(`Contract address: ${result.options.address}`);
};
var server = ganache.server();
server.listen(8545, function (err, blockchain) {
console.log(server);
console.log(" live at port 8545");
});
deploy();
my frontend html/js file
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:8545"));
web3.eth.defaultAccount = web3.eth.accounts[0];
var info = new web3.eth.Contract(
JSON.parse(interface), '0xeD9a9f326F38223a6599309F7201562DfB177997');
console.log(info.methods.GetInfo("test").call());
}
But I get the following error:
index.js:297 Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.
solidty code:
pragma solidity ^0.4.17;
pragma experimental ABIEncoderV2;
contract DVA {
struct Info {
// uint Age;
// bool AgeRestriction;
string DO_Num;
string date;
string time;
string status;
string otherstatus;
string imagehash;
string imagename;
}
mapping (string => Info[]) AllInfo;
function SetInfo(string _DO, string _date, string _time, string _status, string _otherstatus, string _imagehash, string _imagename) public {
Info memory info = Info(_DO,_date,_time,_status,_otherstatus,_imagehash,_imagename);
AllInfo[_DO].push(info);
}
function GetInfo(string _DO) public view returns (string memory) {
// return (AllInfo[_DO].status,AllInfo[_DO].time);
return "hi";
}
}
The code above is the contract code.
The weird thing is, I can call SetInfo but not GetInfo. I have ensured the contract address is valid, and that the ABI is correct as well. In fact, the ABI is retrieved directly upon each compilation of the solidty code as well.
Following a tutorial on Solidity and am working on the front end and end up getting hit with this error
It won't let me fetch the greeting but I can set the greeting everything else works except for the fetch greeting, it won't let me see it even if I set the greeting to something else I can't see it in the console only the error here is the Solidity tutorial
Here is my solidity code
pragma solidity ^0.8.4;
import "hardhat/console.sol";
contract Greeter {
string greeting;
constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
And here is my react code:
import './App.css';
import { useState } from 'react';
import { ethers } from 'ethers'
import Greeter from './artifacts/contracts/Greeter.sol/Greeter.json'
// Update with the contract address logged out to the CLI when it was deployed
const greeterAddress = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
function App() {
// store greeting in local state
const [greeting, setGreetingValue] = useState()
// request access to the user's MetaMask account
async function requestAccount() {
await window.ethereum.request({ method: 'eth_requestAccounts' });
}
// call the smart contract, read the current greeting value
async function fetchGreeting() {
if (typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum)
const contract = new ethers.Contract(greeterAddress, Greeter.abi, provider)
try {
const data = await contract.greet()
console.log('data: ', data)
} catch (err) {
console.log("Error: ", err)
}
}
}
// call the smart contract, send an update
async function setGreeting() {
if (!greeting) return
if (typeof window.ethereum !== 'undefined') {
await requestAccount()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner()
const contract = new ethers.Contract(greeterAddress, Greeter.abi, signer)
const transaction = await contract.setGreeting(greeting)
await transaction.wait()
fetchGreeting()
}
}
return (
<div className="App">
<header className="App-header">
<button onClick={fetchGreeting}>Fetch Greeting</button>
<button onClick={setGreeting}>Set Greeting</button>
<input onChange={e => setGreetingValue(e.target.value)} placeholder="Set greeting" />
</header>
</div>
);
}
export default App;
Any advice would help thx
You need insert the attribute value
value = {greeting}
in the input:
<input onChange={e => setGreetingValue(e.target.value)}
placeholder="Introduce uno nuevo"
value={greeting}
/>
Also initialize with two quotes useState ():
const [greeting, setGreetingValue] = useState ('')
You will probably now have a issue with the metamask nonce, which will tell you that it is too high like message error like this:
Nonce too high. Expected nonce to be 1 but got 2
You will reset account in metamask, or import a new account.
I'm trying to connect a NodeJs server to a solidity contract thats been migrated to a local blockchain and then call the methods on this class via javascript. However, the code returns an error stating that getGreeting() is not defined.
I'm very new Solidity and JavaScript (background in C and Java) so I feel like I'm overlooking something really simple?
My question is how to get it to work and find the method and return "Hello, World!" to the terminal?
My development environment is:
Truffle v5.1.10 (core: 5.1.10)
Solidity - 0.4.25 (solc-js)
Node v12.14.1
Web3.js v1.2.1
Below is the code I'm working on:
// import our compiled JSON
const contractJSON = require("./build/contracts/Hello.json");
const contract = require("#truffle/contract");
const Web3 = require('web3');
// create instance of ganache-cli provider
const web3 = new Web3("http://localhost:9545");
var Hello = contract(contractJSON);
Hello.setProvider(web3);
// if contract is deployed return instance of it and store in app variable
let app = Hello.deployed().then((instance) =>{
return instance;
}).catch(function(error) {
return error;
});
// call a method on our contract via javascript
app.getGreeting().then(() => {
console.log(app);
});
For context the Solidity contract is as follows:
pragma solidity >=0.4.0 <0.7.0;
contract Hello {
string greeting;
constructor() public {
greeting = "Hello, World!";
}
function getGreeting() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
}
For those of you who view this in the future the issue was that I imported the provider incorrectly according to the #truffle/contract documentation here. Also, forgot to fulfill the second promise. Therefore the answer to this solution as of the time of writing is as follows:
const provider = new Web3.providers.HttpProvider("http://localhost:9545");
let Hello = contract(contractJSON);
Hello.setProvider(provider);
Hello.deployed().then((instance) => {
deployed = instance;
return instance.getGreeting();
}).then((result) => {
console.log(result);
}).catch((error) => {
console.log(error);
});
Many thanks to #blex for the assistance.
Your are calling the function "getGreeting()" on the Promise object and not on the contract instance.
// import our compiled JSON
const contractJSON = require("./build/contracts/Hello.json");
const contract = require("#truffle/contract");
const Web3 = require('web3');
// create instance of ganache-cli provider
const web3 = new Web3("http://localhost:9545");
var Hello = contract(contractJSON);
Hello.setProvider(web3);
(async () => {
// Get Contract Instance
let app = await Hello.deployed();
// Call Function
const response = await app.getGreeting();
console.log(response);
})()
When I run truffle test on terminal I get the following error Error: Attempting to run transaction which calls a contract function, but recipient address 0x3ad2c00512808bd7fafa6dce844a583621f3df87 is not a contract address I don't understand why I get this because my build folder is normal meaning if I run truffle migrate --reset the address in the terminal is the same as the address in the build file. when I run truffle migrate it works. Also, every time I run the truffle test the recipient address always changes. I don't know what do to please help.
One other thing this only happens once I use the code selfdestruct(admin); then I get this error. the admin is = to msg.sender which is the first account in the ganache so I don't know what's wrong.
I am using this video. I have done all the other videos of this guy and everything is fine until now at minute 15:11 he does the final test and for him, it works but for me, it gives me the error above.
Anyone, please help
These is my test (javascript)
var CinoCoin = artifacts.require("./CinoCoin.sol");
var CinoCoinSale = artifacts.require("./CinoCoinSale.sol");
contract('CinoCoinSale', function(accounts) {
var tokenInstance;
var tokenSaleInstance;
var admin = accounts[0];
var buyer = accounts[1];
var tokenPrice = 1000000000000000; // in wei 0.01 ether
var tokensAvailable = 750000;
var numberOfTokens;
it('initializes the contract with the correct values', function() {
return CinoCoinSale.deployed().then(function(instance) {
tokenSaleInstance = instance;
return tokenSaleInstance.address
}).then(function(address) {
assert.notEqual(address, 0x0, 'has contract address');
return tokenSaleInstance.tokenContract();
}).then(function(address) {
assert.notEqual(address, 0x0, 'has token contract address');
return tokenSaleInstance.tokenPrice();
}).then(function(price) {
assert.equal(price, tokenPrice, 'token price is correct');
});
});
it('facilitats token buying', function() {
return CinoCoin.deployed().then(function(instance) {
//Grab token instance first
tokenInstance = instance;
return CinoCoinSale.deployed();
}).then(function(instance) {
//Then grab token sale instance
tokenSaleInstance = instance;
//Provision 75% of all tokens to the token sale contract
return tokenInstance.transfer(tokenSaleInstance.address, tokensAvailable, { from: admin})
}).then(function(receipt) {
numberOfTokens = 10;
return tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: numberOfTokens * tokenPrice })
}).then(function(receipt) {
assert.equal(receipt.logs.length, 1, 'triggers one event');
assert.equal(receipt.logs[0].event, 'Sell', 'should be the "Sell" event');
assert.equal(receipt.logs[0].args._buyer, buyer, 'logs the account that purchased the tokens');
assert.equal(receipt.logs[0].args._amount, numberOfTokens, 'logs the number of tokens purchased');
return tokenSaleInstance.tokensSold();
}).then(function(amount) {
assert.equal(amount.toNumber(), numberOfTokens, 'increments the number of tokens sold');
return tokenInstance.balanceOf(buyer);
}).then(function(balance) {
assert.equal(balance.toNumber(), numberOfTokens);
return tokenInstance.balanceOf(tokenSaleInstance.address);
}).then(function(balance) {
assert.equal(balance.toNumber(), tokensAvailable - numberOfTokens);
//Try to buy tokens different from the ether value
return tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: 1 });
}).then(assert.fail).catch(function(error) {
assert(error.message.indexOf('revert') >= 0, 'msg.value must equal number of tokens in wei');
return tokenSaleInstance.buyTokens(800000, { from: buyer, value: numberOfTokens * tokenPrice });
}).then(assert.fail).catch(function(error) {
assert(error.message.indexOf('revert') >= 0, 'connot purchase more tokens than available');
});
});
it('ends token sale', function () {
return CinoCoin.deployed().then(function(instance) {
//Grab token instance first
tokenInstance = instance;
return CinoCoinSale.deployed();
}).then(function(instance) {
//Then grab token sale instance
tokenSaleInstance = instance;
//try to end sale from account other than admin
return tokenSaleInstance.endSale({ from: buyer });
}).then(assert.fail).catch(function(error) {
assert(error.message.indexOf('revert' >= 0, 'must be admin to end sale'));
//End sale as admin
return tokenSaleInstance.endSale({ from: admin });
}).then(function(receipt) {
return tokenInstance.balanceOf(admin);
}).then(function(balance) {
assert.equal(balance.toNumber(), 999990, 'returns all unsold cino coins to admin');
//Check that the token price was reset when selfFestruct was called
return tokenSaleInstance.tokenPrice();
}).then(function(price) {
assert.equal(price.toNumber(), 0, 'token price was reset');
});
});
});
And this is my contract code (solidity)
pragma solidity ^0.4.23;
import "./CinoCoin.sol";
contract CinoCoinSale {
address admin;
CinoCoin public tokenContract;
uint256 public tokenPrice;
uint256 public tokensSold;
event Sell(address _buyer, uint256 _amount);
function CinoCoinSale(CinoCoin _tokenContract, uint256 _tokenPrice) public {
//Assign an admin / an external account connected to the blockchain that has certain priviliges
admin = msg.sender;
//Assign token contract
tokenContract = _tokenContract;
//Token Price how much the token will cost
tokenPrice = _tokenPrice;
}
//multiply function for
function multiply(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x);
}
//Buy tokens
function buyTokens(uint256 _numberOfTokens) public payable {
//Require that the value is equal to tokens
require(msg.value == multiply(_numberOfTokens, tokenPrice));
//Require that there are enough tokens in the contrat
require(tokenContract.balanceOf(this) >= _numberOfTokens);
//Require the transfer is successful
require(tokenContract.transfer(msg.sender, _numberOfTokens));
//Keep track of number of tokens sold
tokensSold += _numberOfTokens;
//Trigger a sell event
Sell(msg.sender, _numberOfTokens);
}
//ending token CinoCoinSale
function endSale()public {
//Only an admin can end the end the sale
require(msg.sender == admin);
//Transfer the amount of token in the sale back to the admin
require(tokenContract.transfer(admin, tokenContract.balanceOf(this)));
//Destroy contract
selfdestruct(admin);
}
}
It says my test are passing when I comment out the selfdestruct(admin); so it seems to be a probelm with that
thanks for the help
glad you fixed the error already. While looking at your code I noticed that the test file is quite difficult to follow because of the large promise chains. I converted the file to async/await, which might be easier to maintain and debug in the future.
I also noticed that you are trying to assert emitted events and reverts by manually checking the logs, and catching the revert exception. I actually wrote a library to make this a bit easier, so I added the code for this as well.
The library can be installed with npm:
npm install truffle-assertions
After this, the new test code should work. I hope this helps, and good luck with your Dapp development.
const CinoCoin = artifacts.require("CinoCoin");
const CinoCoinSale = artifacts.require("CinoCoinSale");
const truffleAssert = require("truffle-assertions");
contract('CinoCoinSale', function(accounts) {
let tokenInstance;
let tokenSaleInstance;
let admin = accounts[0];
let buyer = accounts[1];
let tokenPrice = 1000000000000000; // in wei 0.01 ether
let tokensAvailable = 750000;
it('initializes the contract with the correct values', async function() {
tokenInstance = await CinoCoin.deployed();
tokenSaleInstance = await CinoCoinSale.deployed();
assert.notEqual(tokenSaleInstance.address, 0x0, 'has contract address');
assert.notEqual(await tokenSaleInstance.tokenContract(), 0x0, 'has token contract address');
assert.equal(await tokenSaleInstance.tokenPrice(), tokenPrice, 'token price is correct');
assert.equal(await tokenSaleInstance.admin(), admin, 'admin is correct');
});
it('facilitates token buying', async function() {
tokenInstance = await CinoCoin.deployed();
tokenSaleInstance = await CinoCoinSale.deployed();
await tokenInstance.transfer(tokenSaleInstance.address, tokensAvailable, { from: admin });
const numberOfTokens = 10;
const receipt = await tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: numberOfTokens * tokenPrice });
truffleAssert.eventEmitted(receipt, 'Sell', (ev) => {
return ev._buyer === buyer && ev._amount.toNumber() === numberOfTokens;
});
const tokensSold = await tokenSaleInstance.tokensSold();
assert.equal(tokensSold.toNumber(), numberOfTokens, 'increments the number of tokens sold');
const buyerBalance = await tokenInstance.balanceOf(tokenSaleInstance.address);
assert.equal(buyerBalance.toNumber(), numberOfTokens);
const tokenSaleBalance = await tokenInstance.balanceOf(tokenSaleInstance.address);
assert.equal(tokenSaleBalance.toNumber(), tokensAvailable - numberOfTokens);
truffleAssert.reverts(
tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: 1 }),
null,
'msg.value must equal number of tokens in wei'
);
truffleAssert.reverts(
tokenSaleInstance.buyTokens(800000, { from: buyer, value: numberOfTokens * tokenPrice }),
null,
'connot purchase more tokens than available'
);
});
it('ends token sale', async function () {
tokenInstance = await CinoCoin.deployed();
tokenSaleInstance = await CinoCoinSale.deployed();
truffleAssert.reverts(tokenSaleInstance.endSale({ from: buyer }), null, 'must be admin to end sale');
await tokenSaleInstance.endSale({ from: admin });
const adminBalance = await tokenInstance.balanceOf(admin);
assert.equal(adminBalance.toNumber(), 999990, 'returns all unsold cino coins to admin');
const tokenPrice = await tokenSaleInstance.tokenPrice();
assert.equal(tokenPrice.toNumber(), 0, 'token price was reset');
});
});