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.
Related
Given i have this smart contract in remix
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract DepositWithdraw {
mapping(address => uint256) private balances;
event Deposit(address indexed depositor, uint256 amount);
event Withdrawal(address indexed withdrawer, uint256 amount);
function deposit() public payable {
balances[msg.sender] += msg.value;
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) public {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
emit Withdrawal(msg.sender, amount);
}
function balanceOf(address account) public view returns (uint256) {
return balances[account];
}
}
Deposit by remix ide works, but when I'm trying to deposit using useDapp lib in javascript by using useContractFunction I can't pass the amount to deposit. When I'm redirected to meta mask to accept transaction there is no amount shown.
my front-end code:
import { Contract } from 'ethers';
import { Interface } from 'ethers/lib/utils';
import { useContractFunction } from '#usedapp/core';
const contractAddress = // my contract address;
const ABI = new Interface(
//...copied contract ABI from remix
);
const contract = new Contract(contractAddress, ABI);
const { send } = useContractFunction(contract, 'deposit');
// send(value) will error that deposit function argument length is no correct (it want 0 arguments)
tried adding third argument with options to useContractFunction but no success.
When i call send without arguments it will process to metamask but no amount shown, only gas fees
any ideas?
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
contract Coin {
address public minter;
mapping(address => uint) public balances;
event Sent(address from, address to, uint amount);
constructor() {
minter = msg.sender;
}
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
balances[receiver] += amount;
}
error InsufficientBalance(uint requested, uint available);
function send(address receiver, uint amount) public {
if (amount > balances[msg.sender])
revert InsufficientBalance({
requested: amount,
available: balances[msg.sender]
});
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
While scrolling and attempting to understand ALL aspects of solidity, I can't understand gas fees. Why they say infinite and why it says the "constructor" function is so high.
Remix IDE contains an estimator that is still in active development (February 2023), and it's not perfect yet.
In some cases it's simply not able to estimate the amount of gas that the function is going to consume, and then it shows Infinity or undefined.
For example, it can currently estimate simple assigning to the value, but it's not yet able to estimate increasing the value:
But it doesn't mean that the actual consumption is going to be infinite.
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);
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.7;
contract Transactions {
uint256 transactionCount;
event Transfer(address from, address receiver, uint amount, string message, uint256 timestamp, string keyword);
struct TransferStruct {
address sender;
address receiver;
uint amount;
string message;
uint256 timestamp;
string keyword;
}
TransferStruct[] transactions;
function addToBlockchain(address payable receiver, uint amount, string memory message, string memory keyword) public {
transactionCount += 1;
transactions.push(TransferStruct(msg.sender, receiver, amount, message, block.timestamp, keyword));
emit Transfer(msg.sender, receiver, amount, message, block.timestamp, keyword);
}
function getAllTransactions() public view returns (TransferStruct[] memory) {
return transactions;
}
function getTransactionCount() public view returns (uint256) {
return transactionCount;
}
}
If the code doesn't provide error in Remix, its fine. Solidity extensions/linters in VSCode are not a reliable source of errors.
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;
}
}