Im trying to compile my contracts but solidity cant find a method in a contract that I am importing and using in another contract.
I get this error.
/home/a/Documents/so/contracts/incidents.sol:188:9: TypeError: Member "burn" not found or not visible after argument-dependent lookup in type(contract Token)
Token.burn(_amount);
My import looks like this
import "./token.sol";
this is the function that uses the burn method.
function buyRep(uint _amount) {
uint repAmount = _amount.mul(3);
profiles[msg.sender].uRep.repToGive.add(repAmount);
Token.burn(_amount);
}
the contract the above method is in doesnt inherit the Token contract but when I set it to inherit from the Token contract and just do burn(_amount). I get another error. PLease help me understand this.
This is the function inside the Token contract inside token.sol.
function burn(uint256 _value) public returns (bool success) {
require(balances[msg.sender] >= _value); // Check if the sender has enough
balances[msg.sender] -= _value; // Subtract from the sender
_totalSupply -= _value; // Updates totalSupply
//emit Burn(msg.sender, _value);
return true;
}
Try adding is to derive from your token.sol contract. Derived contracts access all non-private members (state variables and internal functions as well). For more info on inheritance between contracts check out this article.
import "./ContractB.sol";
contract ContractA is ContractB {
function buyRep(uint _amount) public {
burn(_amount);
}
}
'
contract ContractB {
function burn(uint256 _value) public returns (bool success) {
require(balances[msg.sender] >= _value); // Check if the sender has enough
balances[msg.sender] -= _value; // Subtract from the sender
_totalSupply -= _value; // Updates totalSupply
//emit Burn(msg.sender, _value);
return true;
}
}
Related
I've seen some problems with calling functions from other contracts but I believe my problem is fairly genuine to demand a separate question if only to be negated in its possibility.
So I am trying to call a contract within another contract. Is it possible to get the blockhash of a particular block number of the callee contract within my caller? If so how?
Every syntax I've attempted fails for some reason.
Contract A
enter code here
contract DiceGame {
uint256 public nonce = 0;
uint256 public prize = 0;
event Roll(address indexed player, uint256 roll);
event Winner(address winner, uint256 amount);
constructor() payable {
resetPrize();
}
function resetPrize() private {
prize = ((address(this).balance * 10) / 100);
}
function rollTheDice() public payable {
require(msg.value >= 0.002 ether, "Failed to send enough value");
bytes32 prevHash = blockhash(block.number - 1);
bytes32 hash = keccak256(abi.encodePacked(prevHash, address(this), nonce));
uint256 roll = uint256(hash) % 16;
console.log('\t'," Dice Game Roll:",roll);
nonce++;
prize += ((msg.value * 40) / 100);
emit Roll(msg.sender, roll);
if (roll > 2 ) {
return;
}
uint256 amount = prize;
(bool sent, ) = msg.sender.call{value: amount}("");
require(sent, "Failed to send Ether");
resetPrize();
emit Winner(msg.sender, amount);
}
receive() external payable { }
}
Contract B
enter code here
contract RiggedRoll is Ownable {
DiceGame public diceGame;
constructor(address payable diceGameAddress) {
diceGame = DiceGame(diceGameAddress);
}
//Add withdraw function to transfer ether from the rigged contract to an address
//Add riggedRoll() function to predict the randomness in the DiceGame contract and only roll when it's going to be a winner
function riggedRoll(bytes32 riggedHash) public payable {
riggedHash = address(diceGame).blockhash(block.number-1); //I am aware this syntax is broken but I am not able to find a legitimate one to access the data from contract A.
}
//Add receive() function so contract can receive Eth
receive() external payable { }
}
A contract doesn't know when it was last called, unless you explicitly store this information.
Then you can get the block hash using the native blockhash() function (accepts the block number as a parameter).
contract Target {
uint256 public lastCalledAtBlockNumber;
// The value is stored only if you invoke the function using a (read-write) transaction.
// If you invoke the function using a (read-only) call, then it's not stored.
function foo() external {
lastCalledAtBlockNumber = block.number;
}
}
bytes32 blockHash = blockhash(block.number);
I want to call the function of contract A in my contract B. I call the balanceOf function to display the balance normally, but when I call the transfer function, it does display
Note: The called function should be payable if you send value and the value you send should be less than your current balance. I can't even add payable. Can anyone help?
my A contract
function transfer(address _to, uint256 _value)
external
payable
returns (bool success)
{function transfer(address _to, uint256 _value)
external
payable
returns (bool success)
{
require(balancesOf[msg.sender] >= _value);
require(_to != address(0));
require(balancesOf[_to] + _value > balancesOf[_to]);
balancesOf[msg.sender] -= _value;
balancesOf[_to] += _value;
return true;
}
my B contract
interface X {
function balanceOf(address _owner) external view returns (uint256 balance);
function transfer(address _to, uint256 _value)external payable returns (bool success);
}
contract A {
X public token;
constructor(address payable _address){
token = X(_address);
}
function GetbalanceOf(address _owner) external view returns (uint balance) {
return token.balanceOf(_owner);
}
function buy(address xx) external {
token.transfer(xx,100);
}
}
It seems like your not using any msg.value inside the transfer function of contract A henceforth u don't need the function to be payable. Also it might be because there is already a transfer function built in for sending ether.
You should change your transfer name to something else because its conflicting with the already built in transfer function of solidity.
I am trying to create a token using solidity programming, but I keep getting this undeclared identifier error when I compile on remix browser IDE. I am new to solidity and how can I solve this problem?
I have attached my code here:
pragma solidity >=0.4.16 < 0.6.0;
/*declare an interfaced named tokenReceipent so that any contract that implements receiveApproval function counts as a tokenReceipent*/
interface tokenRecipient
{
function receiveApproval(address _from, uint256 _value, address _token, bytes calldata _extraData) external;
}
contract TokenERC20 //create a contract ERC20 and declare public variables of the token
{
string public name;
string public symbol;
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256)public balanceOf; // create mapping with all balances
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value); //create an event on blockchain that will notify clients
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
event Burn(address indexed from,uint256 value); //create an event that notifies clients about the amount burn
constructor(uint256 initialSupply, string memory tokenName, string memory tokenSymbol) // create a construct that initialized tokens to the creator of the contract
public
{
totalSupply = initialSupply*10** uint256(decimals); //update total supply with des 1 1 out
balanceOf[msg.sender]=totalSupply;//give creator all initial tokens
name=tokenName; //set the name and symbol for display purposes
symbol=tokenSymbol;
}
//create an internal function and can only be called by this smartContract
function _transfer(address _from, address _to, uint _value) internal
{
//prevent transfer to 0x0 address
//check that the balance of the sender has enough
//add thesame to the recepient
//insert assert to use static analysis to find bugs in your code,they should never fail
require(_to!=address(0x0));
//subtract from the sender
require(balanceOf[_from]>= _value);
//add thesame to the receipent
require(balanceOf[_to] + _value>= balanceOf[_to]);
uint previousBalances = balanceOf[_from] + balanceOf[_to];
balanceOf[_from] -= _value;
balanceOf[_from] += _value;
emit Transfer(_from , _to, _value);
//assert are used to find static analysis in your code,they should never fail
assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}
//create to transfer function
function transfer(address _to, uint256 _value)
public returns(bool success)
{
_transfer(msg.sender, _to, _value);
return true;
}
//create a from transfer function to transfer tokens from other address
function transferFrom(address _from, address _to, uint256 _value)
public returns(bool success)
{
require(_value <= allowance[_from][msg.sender]);
allowance[_from][msg.sender] -= _value;
_transfer(_from, _to, _value);
return true;
}
//create allowances for other address
//allows spender not spend a certain allowance on your behalf
function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)
public returns(bool success)
{
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, address(this), _extraData);
return true;
}
}
function burn(uint256 _value)
public returns (bool success)
{
require(balanceOf[msg.sender]>= _value);
balanceOf[msg.sender] -= _value; //subtract from the sender
totalSupply -= _value; //update the total supply of tokens
emit Burn(msg.sender, _value);
return true;
}
// function that destroys token from other(users/subscribers) accounts
function burnFrom(address _from, uint256 _value)
public returns(bool success)
{
require(balanceOf[_from] >= _value);
require(_value <= allowance[_from][msg.sender]);
balanceOf[_from] -= _value;
allowance[_from][msg.sender] -= _value;
totalSupply -= _value;
emit Burn(_from, _value);
return true;
}
}
The code is failing to compile due to the error:
browser/Token.sol:73:17: DeclarationError: Undeclared identifier.
if (approve(_spender, _value)) {
^-----^
Your code doesn't declare an approve function, hence the error.
If you didn't write the code yourself, I suggest you check the original source of the code for the approve function.
function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)
public returns(bool success)
{
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, address(this), _extraData);
return true;
}
}
To learn about tokens I suggest you read the OpenZeppelin documentation on tokens:
https://docs.openzeppelin.org/v2.3.0/tokens
You could deploy to a testnet a simple token that uses OpenZeppelin with Remix
pragma solidity ^0.5.0;
import "http://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "http://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
/**
* #title SimpleToken
* #dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `ERC20` functions.
*/
contract SimpleToken is ERC20, ERC20Detailed {
/**
* #dev Constructor that gives msg.sender all of existing tokens.
*/
constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
_mint(msg.sender, 10000 * (10 ** uint256(decimals())));
}
}
You can also ask questions at:
Ethereum Stack Exchange: https://ethereum.stackexchange.com/
Zeppelin Community Forum: https://forum.zeppelin.solutions/
I am pretty new in solidity, and this is so weird.
I got this piece of codes working in the JavaScript VM on Remix to get the reentrance attack working.
However, When I run the contract attacker on train, I called the deposit() function in the contract attacker. No money is transfred. I am wondering why it this.
pragma solidity^0.5.0;
contract TestToken {
mapping (address => uint256) balances;
constructor() public {
total = 0;
}
function deposit() public payable returns (bool success) {
if (balances[msg.sender] + msg.value < msg.value) return false;
if (total + msg.value < msg.value) return false;
balances[msg.sender] += msg.value;
total += msg.value;
return true;
}
}
contract Attacker {
// uint256 count;
TestToken token;
uint256 _value;
event logString(uint256, uint256, uint256);
constructor () public payable {
}
function deposit(address _tokenAddress) public payable {
token = TestToken(_tokenAddress);
_value = address(this).balance;
// token.deposit.value(_value)();
_tokenAddress.call.value(address(this).balance)(abi.encode(bytes4(keccak256("deposit()"))));
}
function attack(address _tokenAddress) public {
token = TestToken(_tokenAddress);
token.withdraw(_value);
}
function() external payable {
emit logString(address(this).balance, msg.value, address(token).balance);
if (address(token).balance > msg.value) token.withdraw(msg.value);
}
function getBalance() public view returns(uint) { return address(this).balance; }
function getTestTokenBalance() public view returns(uint) { return address(token).balance; }
}
I spent three days in this problem. It is not about the problem now, I just wondering what kind of a problem can stuck me so long.
If you can point it out, I would say you are smarter than me.Pls
// This line is not working.
_tokenAddress.call.value(address(this).balance)(abi.encode(bytes4(keccak256("deposit()"))));
I'm learning Solidity from official documentation and stack on an exercise where I create simple coin:
pragma solidity ^0.4.20; // should actually be 0.4.21
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;
}
function mint(address receiver, uint amount) public {
if (msg.sender != minter) return;
balances[receiver] += amount;
}
function send(address receiver, uint amount) public {
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
When i try to compile i got a syntax error on the last line:
emit Sent(msg.sender, receiver, amount);
I tried to compile it in Remix and VS Code but got the same error message.
Can somebody help me pls?
The emit keyword was added in Solidity 0.4.21. Prior to that version, you emit events by using just the event name.
Sent(msg.sender, receiver, amount);
You can view the proposal here.