contract Counter {
uint public Count = 0;
event Increment(uint value);
event Decrement(uint value);
function getCount() view public returns(uint) {
return Count;
}
function Increment() public {
Count += 1;
emit Increment(Count);
}
function Decrement() public {
count -= 1;
emit Decrement(Count);
}
}
please what is already defined or wrong
As said #Yilmaz, your issue refers that events and functions name have the same name.
To solve this issue, you must change name to events or function names.
In the following lines, I put an example how you will solve it:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Counter {
uint public Count = 0;
// NOTE: I changed name to these two events
event EventIncrement(uint value);
event EventDecrement(uint value);
function getCount() view public returns(uint) {
return Count;
}
function Increment() public {
Count += 1;
emit EventIncrement(Count);
}
function Decrement() public {
Count -= 1;
emit EventDecrement(Count);
}
}
Related
I'm running into a problem with solidity with structures containing arrays, can you help me see what I'm missing?Any help would be greatly appreciated!
struct Info {
uint a;
uint256 b;
uint[] data;
}
mapping(address => Info) infos;
function set() public {
infos[msg.sender].a = 1;
infos[msg.sender].b = 2;
infos[msg.sender].data.push(3);
}
function get() public {
infos[msg.sender].a; //yes It is equal to 1
infos[msg.sender].b; //yes It is equal to 2
infos[msg.sender].data[0]; //The problem here is that anyone calling this function can read data[0]=3
}
I am a little confused as to what you require, but first solution I have provided modifies your Smart Contract such that mapping object infos and the getter function is both private (available only in the Contract defined).
contract test{
struct Info {
uint a;
uint b;
uint[] data;
}
mapping(address => Info) private infos;
function set() public {
infos[msg.sender].a = 1;
infos[msg.sender].b = 2;
infos[msg.sender].data.push(3);
}
function get() private view{
infos[msg.sender].a; //yes It is equal to 1
infos[msg.sender].b; //yes It is equal to 2
infos[msg.sender].data[0]; //The problem here is that anyone calling this function can read data[0]=3
} }
Second solution is to add something called 'require' in the getter function so that only the person who deploys the Smart Contract can view the array index. The constructor function assigns the person who deploys the contract as the 'owner'.
contract test{
struct Info {
uint a;
uint b;
uint[] data;
}
address owner;
constructor() {
owner = msg.sender;
}
mapping(address => Info) infos;
function set() public {
infos[msg.sender].a = 1;
infos[msg.sender].b = 2;
infos[msg.sender].data.push(3);
}
function get() public view{
infos[msg.sender].a; //yes It is equal to 1
infos[msg.sender].b; //yes It is equal to 2
require(owner == msg.sender, 'you cannot read this data, you are not the owner!');
infos[msg.sender].data[0]; //The problem here is that anyone calling this function can read data[0]=3
}
}
Let me know if I have misunderstood your question.
This is my first Solidity project.
I'm trying to create a kind of supply chain, more than anything just practice code.
I came across a problem that I couldn't solve or find the solution online.
Problem: I want to get the user ID and save it in each function so it would look like...
function Customer() public {
checked = Process.Received;
status = Process.NotPaid;
//userid = Process.< THE ID >
}
I tried with this ...
function getStruct() public
view
returns (string, uint)
{
return (User);
}
But keeps on asking me to have the data located in memory. Which I tried but won't work for me.
Full code:
pragma solidity ^0.5.1;
contract SupplyChain {
enum Process {
Unknown,
Checked,
Received,
Paid,
NotPaid
}
Process public status;
Process public checked;
Process public userid;
address user;
struct User {
uint _id;
string _firstName;
string _lastName;
}
constructor() public {
status = Process.Unknown;
user = tx.origin;
}
function addUser(
uint256 id,
string memory _firstName,
string memory _lastName
) public{
}
// NOT FINISHED NEED TO RETURN USER ID TO PRINT IN TRACKERS.
function getStruct() public
view
returns (string, uint)
{
return (User);
}
function Factory() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function TransportOne() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function Deposit() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function TransportTwo() public {
checked = Process.Checked;
status = Process.NotPaid;
// print userid
}
function Customer() public {
checked = Process.Received;
status = Process.NotPaid;
// print userid
}
}
There is no print in solidity, you can try to use events for logging.
If you just want to debug, you can try Remix IDE.
I am trying to create a public funcion that returns an array,
this is the error
Return argument type mapping(uint256 => struct ItemList.Item storage
ref) is not implicitly convertible to expected type (type of first
return variable) uint256[] memory.
pragma solidity ^0.5.0;
contract ItemList {
uint public itemCount = 0;
mapping(uint256 => Item) public items;
event ItemCreated (
uint id,
string proofdocument
);
struct Item {
uint id;
string proofdocument;
}
constructor() public {
}
function createItem(string memory _proofdocument) public {
itemCount++;
items[itemCount] = Item(itemCount, _proofdocument);
emit ItemCreated(itemCount, _proofdocument);
}
function getItems() public pure returns(uint256[] memory ) {
return items; <----------ERROR
}
}
Thanks Andrea
You can get every item in the loop via web3.js library
const array = []
for (let i = 0; i < itemCount; itemCount += 1) {
array.push(contract.getItem(i)) // where getItem do items[I] in solidity
}
Or you can use pragma experimental version:
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract ItemList {
uint public itemCount = 0;
struct Item {
uint id;
string proofdocument;
}
Item[] items;
constructor() public {}
function createItem(string memory _proofdocument) public {
itemCount++;
items.push(Item(itemCount, _proofdocument));
}
function getItems() external view returns(Item[] memory) {
return items;
}
}
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()"))));
Let's start with my solidity code :
pragma solidity ^0.4.18;
contract Voting {
address mainAddress;
bytes32[] candidateNames;
mapping(bytes32 => uint) candidateVotes;
mapping(bytes32 => bytes32) candidatesDetails;
address[] voters;
function Voting() public {
mainAddress = msg.sender;
}
modifier isMainAddress {
if (msg.sender == mainAddress) {
_;
}
}
function getAllCandidates() public view returns (bytes32[]) {
return candidateNames;
}
function setCandidate(bytes32 newCandidate) isMainAddress public {
candidateNames.push(newCandidate);
}
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
function getVote(bytes32 candidate) public view returns (uint) {
return candidateVotes[candidate];
}
function setDescrption(bytes32 candidateName, bytes32 candidatesDesc) isMainAddress public {
candidatesDetails[candidateName] = candidatesDesc;
}
function getDescription(bytes32 candidateName) public view returns (bytes32){
return candidatesDetails[candidateName];
}
function getCurrentAddress() public view returns (address) {
return msg.sender;
}
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
}
The functions : Voting(), getAllCandidates(), setCandidate(), getVote(), setDescription(), getDescription(), getCurrentAddress() works fine when called multiple times. So, I guess we can ignore them for now.
The function setVote() runs fine the first time it executes ie. when a person votes for once. The problem arises when the same person tries to vote the second time. It gives the following error :
This might be a beginners mistake but I have been trying to fix this for 2 days straight and now I really need help.
Also,
I use Remix - browser based IDE to run/check my solidity code.
I use Ganache for test accounts.
Thanks.
The function in question:
function setVote(bytes32 candidate) public {
require(validVoters());
candidateVotes[candidate] = candidateVotes[candidate] + 1;
voters.push(msg.sender);
}
Note that validVoters() must return true for this function to succeed. If it returns false, the require will fail and revert the transaction. Also note that at the end of the function, msg.sender is added to the array voters.
Let's take a look at validVoters():
function validVoters() public view returns (bool) {
for(uint i = 0; i < voters.length ; i++){
if (voters[i] == msg.sender) {
return false;
}
}
return true;
}
This function returns false if msg.sender is in voters, which we know will be the case after the account has voted once.
So the second time through, validVoters() returns false, which causes require(validVoters()) in setVote() to revert the transaction.