I have an innocent looking contracts that work painlessly in Remix. Test contract can easily call Another if I use JavaScript VM in Remix.
I also have ganache-cli running on port 7454. If I connect Remix to ganache-cli, each of these contracts work well individually. But I cant call Another from Test. Remix console says transact to Test.send errored: VM Exception while processing transaction: revert
My contracts look like:
pragma solidity 0.4.25;
contract Another {
uint public balance;
function sendToAnother() public {
balance += 10;
}
}
contract Test {
function send(address another) public {
Another(another).sendToAnother();
}
}
One suspicion I have is - am I picking up the address of the Another contract correctly? I am copying it from Remix's Deployed Contracts tab.
Related
I want to make a smart contract that deposits UST on the eth anchor protocol, by using the deposit function. Here you can find the docs of this function I try to call. https://docs.anchorprotocol.com/ethanchor/ethanchor-contracts/router . The function gets called trough a proxy contract. I found the implementation address by reading the proxy contract on etherscan.
TestContracts on Ropsten testnet:
proxy: 0x7537aC093cE1315BCE08bBF0bf6f9b86B7475008
etherscan: https://ropsten.etherscan.io/address/0x7537aC093cE1315BCE08bBF0bf6f9b86B7475008
implementation (ROUTERV2): 0x2ba0010394eb3e41454c7d79c0fb6e0deb67284b
etherscan: https://ropsten.etherscan.io/address/0x2ba0010394eb3e41454c7d79c0fb6e0deb67284b
I imported the ROUTERV2 contract for calling the proxy with the abi of the implementation.
my execution order is:
deploying the contract
approving the contract for spending the tokens from the sender using ethers.
approveUST function on smart contract (I am not sure if this is necessary)
calling the depositStable function.
I get the following error when calling the depositStale function UNPREDICTABLE_GAS_LIMIT;
Below You see the contract I try to make. It should take the UST of the user and deposit it on eth anchor.
Here is a github link to the hardhat repo of the contract so you can simulate the bug and hopefully help me solving this issue.
https://github.com/tijgersoftware/Terra-anchor
I thank you for taking the time to read my question!
contract Anchor {
address public proxy;
address public operator;
address public USTAddress;
constructor(
address proxy_,
address operator_,
address USTAddress_
) public {
proxy = proxy_;
operator = operator_;
USTAddress = USTAddress_;
}
function approveUST() public {
ERC20(USTAddress).approve(
address(this),
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
);
}
function initDepositStable(uint256 amount) public {
RouterV2(proxy).initDepositStable(amount);
}
function depositUST(uint256 amount) public {
// InterfaceOfImplementationContract(proxyAddress).MethodBeingCalled(
// parameter,
// parameter,
// parameter
// );
ERC20(USTAddress).approve(
address(this),
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
);
RouterV2(proxy).depositStable(operator, amount);
}
}
tags: solidity, smart contracts, ethereum, anchor protocol, terra, brdige trasfer.
I am looking to explore the option of creating a digital certificate (as in proof) when someone has completed a portion of training, and for this to be issued on an EVM-compatible blockchain using Solidity.
I have prototyped using ERC721 NFTs to encode a "certificate" however, I'd like to prevent recipients from being able to transfer these certificates. To prevent transfer, I attempted to use the Pause.sol functionality from OpenZeppelin, however, this would result in the entire contract being paused, as opposed to a specific tokenId.
Does anyone have any recommendation on an approach? Am I overcomplicating it if I don't want recipients to be able to trade the certificates (i.e. for them to remain static)? Any pointers would be much appreciated!
The simplest and most raw solution is to just set a mapping value.
pragma solidity ^0.8;
contract TrainingResults {
enum Stage {
NONE,
STAGE_1,
STAGE_2,
COMPLETED
}
mapping (address => Stage) public participantStage;
function setParticipantStage(address _graduate, Stage _stage) external {
require(msg.sender == address(0x123), "Not authorized");
participantStage[_graduate] = _stage;
}
}
Or if you want them to be able to see some kind of NFT in their wallet (that supports NFTs), you can modify the ERC-721 contract to disallow transfers.
For example the OpenZeppelin implementation uses a function named _beforeTokenTransfer() (GitHub link) that can be overwritten to disallow transfers altogether.
pragma solidity ^0.8;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract TrainingResults is ERC721 {
constructor() ERC721("TrainingResults", "TR") {}
function _beforeTokenTransfer(address from,address to, uint256 tokenId) override internal {
// Allow only for the admin
// as this function is called on token mint as well
require(msg.sender == address(0x123), "Cannot transfer tokens");
}
}
I am relatively new to Solidity, I am trying to fetch the price of a pair with the following contract:
contract Uniswap {
constructor () public payable {
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
// calculate price based on pair reserves
function getTokenPrice(address pairAddress, uint amount) public payable returns(uint)
{
IUniswapV2Pair pair = IUniswapV2Pair(pairAddress);
IERC20 token1 = IERC20(pair.token1());
(uint Res0, uint Res1,) = pair.getReserves();
// decimals
uint res0 = Res0*(10**token1.decimals());
return((amount*res0)/Res1); // return amount of token0 needed to buy token1
}
}
but when I try to run on Remix the getTokenPriceit returns me the following error message:
The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
Any idea why? I am trying to fetch the price of ETH/USDT so the using this website (https://v2.info.uniswap.org/pair/0x0d4a11d5eeaac28ec3f61d100daf4d40471f1852) and with the pair address at the end of the URL. Thanks for the help!
When you deploy a contract in Remix, it deploys to a local network. (By default. You can change it and deploy to mainnet as well, if you inject a production Infura provider for example.)
The Uniswap pair contract 0x0d4a11... does not exist on the local network.
The easiest solution is to deploy your contract on the mainnet (where the 0x0d4a11... Uniswap pair contract exists).
Or you can find another Uniswap pair on a public testnet (well-known are Rinkeby, Ropsten, Goerli, and Kovan), and deploy your contract on the same testnet. Don't forget to change the testnet address of the uniswap pair that you pass to your getTokenPrice() function.
Or you can deploy the Uniswap pair contract and all of its dependencies and change the dependencies addreses (which is a lot of work - my guess is that it's dependend on the Uniswap router contract, the actual token contracts of the pair, maybe they are dependend on some other contract, ...) to your local network. From here it's the same - deploy your contract to the local network, and call the getTokenPrice() with the correct pair address.
You may also invoke uniswap's Subgraph using javascript
Following smart contract works fine in Remix and Ganache. However doesn't work on private ethereum blockchains like Kaleido or Azure. What am I missing. When I call setA it consumes all gas and then fails.
pragma solidity ^0.4.24;
contract TestA {
uint public someValue;
function setValue(uint a) public returns (bool){
someValue = a;
return true;
}
}
contract TestB {
address public recentA;
function createA() public returns (address) {
recentA = new TestA();
return recentA;
}
function setA() public returns (bool) {
TestA(recentA).setValue(6);
return true;
}
}
I tried your contract in Kaleido, and found even calling eth_estimateGas with very large numbers was resulting in "out of gas".
I changed the setValue cross-contract call to set a gas value, and I was then able to call setA, and estimating the gas for setA showed just 31663.
recentA.setValue.gas(10000)(6);
I suspect this EVM behavior is related to permissioned chains with a gasprice of zero. However, that is speculation as I haven't investigated the internals.
I've also added eth_estimateGas, and support for multiple contracts in a Solidity file, to kaleido-go here in case it's helpful:
https://github.com/kaleido-io/kaleido-go
Another possibility for others encountering "out of gas" calling across contracts - In Geth if a require call fails in a called contract, the error is reported as "out of gas" (rather than "execution reverted", or a detailed reason for the require failing).
You are hitting the limit of gas allowed to be spent per block. Information about gas limit is included into every block, so you can check what's this value is right now in your blockchain. Currently on Ethereum MainNet, GasLimit (per block) is about 8 millions (see here https://etherscan.io/blocks)
To fix this, you can start your blockchain with modified genesis file. Try to increase value of gasLimit parameter in your genesis file, which specifies the maximum amount of gas processed per block. Try "gasLimit": "8000000".
Try to discard the return statement of setValue method in contract TestA.
pragma solidity ^0.4.24;
contract TestA {
uint public someValue;
function setValue(uint a) public {
someValue = a;
}
}
I've deployed the ScoreStore contract to test RPC, and it works fine. This is ScoreStore contract:
pragma solidity ^0.4.4;
contract ScoreStore
{
mapping(string => int) PersonScores;
function SetScore(string name, int score) {
if(PersonScores[name]>0){
throw;
}
else{
PersonScores[name] = score;
}
}
function GetScore(string name) returns (int){
return PersonScores[name];
}
}
Now I want to use this contract on another contract named MyGame, the contract code is as follows:
pragma solidity ^0.4.4;
contract IScoreStore{
function GetScore(string name) returns (int);
}
contract MyGame{
function ShowScore(string name) returns (int){
// Interface takes an address of the existing contract as parameter
IScoreStore ss = IScoreStore(0x6c38cfb90e8fb1922e61ea4fbe09d29c7751bf82);
return ss.GetScore(name);
}
}
When I give this command on truffle console, mg.ShowScore.call("Anna")
it thorws this:
Error: VM Exception while processing transaction: revert
at XMLHttpRequest._onHttpResponseEnd (C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:509:1)
at XMLHttpRequest._setReadyState (C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:354:1)
at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2\lib\xhr2.js:64:1)
at XMLHttpRequest.request.onreadystatechange (C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\httpprovider.
at C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\truffle-provider\wrapper.js:134:1
at C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\requestmanager.js:86:1
at Object.InvalidResponse (C:\Users\Fariha.Abbasi\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3\lib\web3\errors.js:38:1)
Any idea, what i am doing wrong?
Any help is appreciated, P.S: testrpc is already running.
I was able to compile both the contracts in remix and call the ShowScore function after setting some value from ScoreStore contract successfully.
Are you sure the address given to the interface is correct? Because I got the same revert error when I gave an invalid address.