"Internal JSON-RPC error" when calling Solidity smart contract function - javascript

I'm building a DApp and i'm trying to use a function in my smart contract to get the actual ethereum value, and then use it to convert a certain amount of dollars into its Ethereum value. When trying to do so, i'm getting "Internal JSON-RPC error" and i can't understand why. The contract has been correctly compiled and migrated.
This is the js code to call the function:
App.contracts.TravelCoin.deployed().then(function(instance) {
flightsInstance = instance;
return flightsInstance.GetValueInEth(dollarPrice);
}).then(function(value) {
console.log("inside function");
cell2.innerHTML = value;
}).catch(function(err) {
console.log(err.message);
});
This is the Solidity smart contract code:
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract TravelCoin{
AggregatorV3Interface internal priceFeed;
constructor() {
priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e);
}
function getLatestPrice() public view returns (uint) {
(, int price,,,) = priceFeed.latestRoundData();
return uint (price*1e18);
}
function GetValueInEth(uint dollarsAmount) public view returns (uint) {
uint valuePrice = uint(getLatestPrice());
uint ethAmount = (dollarsAmount*1e18)/valuePrice;
return ethAmount;
}
}
If you want to reproduce the issue, here it is the repository link: https://github.com/CicaMatt/TravelCoin.git
I really don't know what causes this issues, as i call the other function the same way but i'm not getting any problem.

Related

Getting "undefined" in my frontend react, when requesting chainlink random number

I have already deployed a smart contract with chainlink VRFConsumerBase named game contract as shown below to get a random number. When I am calling from front-end to get random number, it is showing "undefined" as show in the picture below.
Error Message
async BelowSeven(amount){
const gameContract=this.state.gameContract
let firstDiceNumber =(await gameContract.getRandomNumber())
window.alert("Rolling Dies")
firstDiceNumber=await gameContract.randomResult
console.log(firstDiceNumber)
window.alert("Completed")
//let secondDiceNumber =(await gameContract.getRandomNumber())
//secondDiceNumber=await gameContract.randomResult
//const result= firstDiceNumber+secondDiceNumber
//console.log(secondDiceNumber)
}
Random Number Generating Contract (game Contract):
pragma solidity >=0.4.0 <0.9.0;
import "#chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
contract game is VRFConsumerBase{
uint public randomResult;
bytes32 internal keyHash;
uint internal fee;
constructor() VRFConsumerBase(0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B,
0x01BE23585060835E02B77ef475b0Cc51aA1e0709) public
{
keyHash=0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311;
fee=0.1 *10**18;
}
function getRandomNumber() public returns(bytes32 requestId){
return requestRandomness(keyHash,fee);
}
function fulfillRandomness(bytes32 requestId,uint randomness) internal override{
randomResult=randomness%7;
}
function contractBalance() public view returns(uint){
return address(this).balance;
}
function contractFund() external payable{
}
}

how to approve the spend of ERC20 tokens from the javascript file?

I have two contracts ERC20, and ERC721.
and everytime erc721 transferFrom function is called, I want to send some erc20 tokens to the creator (minter) of the ERC721.
After some research, I've found that I have to do two things.
call ERC20.transferfrom in ERC721 transferFrom function
Approve the spending of erc20 tokens from the frontend
it seems like the second is giving me some problems. Please see my code below:
Your help will be very much appreciated.
++ I am also not so sure if I am calling ERC20.transferFrom correctly from ERC721 contract. Is this the correct way to do it?
ERC721 contract:
import "../openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
import "../openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
import "../openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol";
import "../openzeppelin-contracts/contracts/math/SafeMath.sol";
import "../openzeppelin-contracts/contracts/utils/Address.sol";
import "../openzeppelin-contracts/contracts/utils/Counters.sol";
import "./ERC20Token.sol";
contract NFTtoken is ERC721 {
.
.
.
ERC20Token Erc20Contract;
constructor(address tokenAddress) ERC721("NC NFT example", "NCNFT") {
owner = msg.sender;
decimals = 0;
Erc20Contract = ERC20Token(tokenAddress);
}
function mint(string calldata nftName) external payable {
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
nftInfo[msg.sender].name = nftName;
nftInfo[msg.sender].creator = msg.sender;
allValidTokenIndex[newItemId] = allValidTokenIds.length;
allValidTokenIds.push(newItemId);
_tokenIds.increment();
}
function transferNFT(address from, address to, uint256 tokenId) public returns (bool){
transferFrom(from, to, tokenId);
Erc20Contract.transferFrom(to, nftInfo[from].creator, 10);
}
}
.
.
.
app.js
transferNFT: function() {
NFTContract.deployed().then(function(contractInstance) {
let toAddress = $("#to-address").val();
// function transferFrom(address _from, address _to, uint256 _tokenId) public payable {
let NFTid_temp = $("#nft-id").val();
let NFTid = NFTid_temp.substring(7);
console.log("to = " + toAddress);
console.log("nftid = " + NFTid);
Voting.deployed().then(function(votingcontractInstance) { votingcontractInstance.approve(contractInstance.address, votingcontractInstance.balanceOf(web3.eth.accounts[1]))});
contractInstance.transferNFT(web3.currentProvider.selectedAddress, toAddress, NFTid, {gas: 140000, from: web3.eth.accounts[0]});
})
}
error message
app.js:10169 Uncaught (in promise) BigNumber Error: new BigNumber() not a number: [object Object]
at raise (http://localhost:8080/app.js:10169:25)
at http://localhost:8080/app.js:10157:33
at new BigNumber (http://localhost:8080/app.js:9184:67)
at new BigNumber (http://localhost:8080/app.js:9194:25)
at toBigNumber (http://localhost:8080/app.js:2084:12)
at Object.toTwosComplement (http://localhost:8080/app.js:2095:21)
at SolidityTypeAddress.formatInputInt [as _inputFormatter] (http://localhost:8080/app.js:2995:38)
at SolidityTypeAddress.SolidityType.encode (http://localhost:8080/app.js:3648:17)
at http://localhost:8080/app.js:15577:29
at Array.map (<anonymous>)
I suspect this line:
votingcontractInstance.balanceOf(web3.eth.accounts[1]))
Can you check its type? I think it returns "string" but it must be number. If it is string either wrap it with Number
Number(votingcontractInstance.balanceOf(web3.eth.accounts[1])))
Or use web3.utils.toBN()
web3.utils.toBN(votingcontractInstance.balanceOf(web3.eth.accounts[1])))

Contract throws Invalid address when using send() function in solidity 0.4.6

This is the solidity code that I am trying. Compiling of the code works fine. However, when I call the function send() via javascript it throws exception : throw new Error('invalid address');
pragma solidity ^0.4.6;
contract Agreement {
address owner;
address seller;
uint amount;
function Agreement(address _seller,uint _amount) {
owner = msg.sender; seller=_seller; amount=_amount;
}
function send(){
if (owner.balance < amount) throw;
if (seller.balance + amount < seller.balance) throw;
if(!seller.send(amount))throw;
}
}
This is the javascript code
var compiled = web3.eth.compile.solidity(contractRaw);
var contract = web3.eth.contract(compiled.info.abiDefinition);
var nContract = contract.new('0x61e323dcf5e116597d96558a91601f94b1f80396',web3.toWei(10, "ether"),{from:this.web3.eth.coinbase, data: compiled.code, gas: 380000}, function(e, contractDetails){
if(!e) {
if(!contractDetails.address) {
console.log("Contract transaction send: TransactionHash: " + contractDetails.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contractDetails.address);
console.log(contractDetails.send())
}
}
});
Whenever the code runs, it throws invalid address error and crashes.
That address in fact exists (etherscan link) > , but it's not a contract address. If was, must open like this.
When you deploy your contract to etherium, you must copy the hash resulted on contract creation (transaction hash) and search for it on etherscan. It will open all transaction details, including the created contract hash. Use that hash.
Try 61e323dcf5e116597d96558a91601f94b1f80396, without the 0x

Getting the address of a contract deployed by another contract

I am trying to deploy a contract from another factory contract and then return the address of the newly created contract. The address it returns however is the transaction hash not the contract address. I believe this is because the contract is not yet mined when the address is returned. When I deploy a contract using the web3 deploy it seems to wait until the contract is deployed before outputting the address.
The factory contract:
contract Factory {
mapping(uint256 => Contract) deployedContracts;
uint256 numContracts;
function Factory(){
numContracts = 0;
}
function createContract (uint32 name) returns (address){
deployedContracts[numContracts] = new Contract(name);
numContracts++;
return deployedContracts[numContracts];
}}
This is how I am calling the createContract function.
factory.createContract(2,function(err, res){
if (err){
console.log(err)
}else{
console.log(res)
}
});
Consider the below example. There are a number of ways you can get the address of the contract:
contract Object {
string name;
function Object(String _name) {
name = _name
}
}
contract ObjectFactory {
function createObject(string name) returns (address objectAddress) {
return address(new Object(name));
}
}
1 Store the Address and Return it:
Store the address in the contract as an attribute and retrieve it using a normal getter method.
contract ObjectFactory {
Object public theObj;
function createObject(string name) returns (address objectAddress) {
theObj = address(new Object(name));
return theObj;
}
}
2 Call Before You Make A Transaction
You can make a call before you make a transaction:
var address = web3.eth.contract(objectFactoryAbi)
.at(contractFactoryAddress)
.createObject.call("object");
Once you have the address perform the transaction:
var txHash = web3.eth.contract(objectFactoryAbi)
.at(contractFactoryAddress)
.createObject("object", { gas: price, from: accountAddress });
3 Calculate the Future Address
Otherwise, you can calculate the address of the future contract like so:
var ethJsUtil = require('ethereumjs-util');
var futureAddress = ethJsUtil.bufferToHex(ethJsUtil.generateAddress(
contractFactoryAddress,
await web3.eth.getTransactionCount(contractFactoryAddress)));
We ran across this problem today, and we're solving it as follows:
In the creation of the new contract raise an event.
Then once the block has been mined use the transaction hash and call web3.eth.getTransaction:
http://web3js.readthedocs.io/en/1.0/web3-eth.html#gettransaction
Then look at the logs object and you should find the event called by your newly created contract with its address.
Note: this assumes you're able to update the Solidity code for the contract being created, or that it already calls such an event upon creation.

Angular JS: Promise returns resource

REPOSITORY METHOD
public int CalculateSoundVolume(string roomName, int currentUser)
{
{
//Business Logic
return finalApplauseVolume; //**say returning 75**
}
catch (Exception ex)
{
_logger.LogException(ex);
throw;
}
}
WEB API CONTROLLER
public IHttpActionResult CalculateSoundVolume()
{
try
{
//Some Logic
var result = _applauseRepository.CalculateSoundVolume(huddleName, currentUser);
return Ok(result); // **it returns 75 here in result**
}
catch (Exception ex)
{
_logger.LogException(ex);
throw;
}
}
CLIENT SIDE CONTROLLER (ANGULAR JS)
public calculateSoundVolume()
{
var promise = this.applauseService.calculateSoundVolume();
promise.then((res) => {
this.$log.debug("Sound Volume : ", res);
// Getting Resource [0] : '7' and [1] : '5'
});
}
SERVICE
calculateSoundVolume()
{
return this.soundVolume.get().$promise;
}
Now here the scenario is i am returning an integer value from my Repository method. (say 75). I the WEB API controller the value is recieved as 75 in result.
But the issue is in "res" in my client side controller i am recieving a Resource as [0]:'7' and [1]: '5' i.e the actual and expected value is not recieved. Please suggest any solution
This same issue was happening to me. Turns out the $promise, instead of returning the int, returns an object that breaks the digits of the integer into different indexes in an array along with some other information the promise uses. I was able to resolve the issue by wrapping the integer with a JObject and passing that from the Web API instead of the integer.
So your Web API would look like this:
public JContainer CalculateSoundVolume()
{
try
{
//Some Logic
var result = new JObject(new JProperty("soundVolume", _applauseRepository.CalculateSoundVolume(huddleName, currentUser)));
return result;
}
catch (Exception ex)
{
_logger.LogException(ex);
throw;
}
}
and your client side controller would change to this:
public calculateSoundVolume()
{
var promise = this.applauseService.calculateSoundVolume();
promise.then((res) => {
this.$log.debug("Sound Volume : ", res.soundVolume);
});
Hope that helps
-- Edit --
I should clarify that I am using the Newtonsoft library for JSON in the above code. I found another stackOverflow question which relates Here. In conclusion Chandermani is correct that you should try sending a valid JSON object back from the server instead.

Categories