Error :The transaction has been reverted to the initial state - ethereum

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
contract modifierExample{
address admin ;
constructor() public {
admin == msg.sender;
}
modifier isAdmin {
require(admin == msg.sender,"you are not the owner");
_;
}
modifier isExp(uint exp) {
if(exp >= 5)
_;
else
revert("you are not experienced");
}
struct employeeDetails{
uint iD;
string name;
uint age;
}
mapping (uint => employeeDetails) getDetailsByNum;
function enterDetails(uint number,
uint iD,
string memory name,
uint age) public isAdmin isExp(5) {
employeeDetails memory EmployeeDetails = employeeDetails(iD,name,age);
getDetailsByNum[number] = EmployeeDetails;
}
function getDetailsByNumber(uint number) public view returns (employeeDetails memory) {
return getDetailsByNum[number];
}
}
Why did I encounter this error?????
After entering the details it is throwing me an error as mentioned below
transact to modifierExample.enterDetails errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Reason provided by the contract: "you are not the owner".
Debug the transaction to get more information.

Your enterDetails() function uses the isAdmin modifier.
As per the following code, any function that uses the isAdmin modifier, can be executed only by the address that deployed the contract.
address admin ;
constructor() public {
admin == msg.sender;
}
modifier isAdmin {
require(admin == msg.sender,"you are not the owner");
_;
}
You're getting the you are not the owner error because you're trying to execute the function from some other address than the admin.

Related

enable 2 users to use my contract at the same time with different states in Solidity

I'm new in solidity, and I was trying to create a simple purchase contract between 2 users, with different states as below:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract purchase {
uint public value;
struct Users {
address payable seller;
address payable buyer;
}
Users public users;
uint256 public contractID;
enum State{Created, Locked, Release, Inactive}
State public state;
constructor() payable {
users.seller = payable(msg.sender);
value = msg.value / 2;
}
///The function can't be called at the current state.
error InvalidState();
///Only buyer/buyer can call this function
error Onlybuyer();
///Only Seller can call this function
error OnlySeller();
modifier inState(State state_){
if (state != state_) {
revert InvalidState();
}
_;
}
modifier onlybuyer(){
if (msg.sender != users.buyer) {
revert Onlybuyer();
}
_;
}
modifier onlySeller(){
if (msg.sender != users.seller) {
revert OnlySeller();
}
_;
}
mapping(uint => Users) public contractUsers;
mapping(uint => State) public contractState;
function confirmPurchase() external inState(State.Created) payable {
contractID ++;
require(msg.value == (2*value), "Please send in 2X the purchase amount");
users.buyer = payable(msg.sender);
state = State.Locked;
}
function confirmRecieved() external onlybuyer inState(State.Locked) {
state = State.Release;
users.buyer.transfer(value);
}
function paySeller() external onlySeller inState(State.Release){
state = State.Inactive;
users.seller.transfer(3 * value);
}
function abort() external onlySeller inState(State.Created){
state = State.Inactive;
users.seller.transfer(address(this).balance);
}
}
I would like to ask, how I can enable 2 sellers to use the contract at the same time with different states? or how I enable many users to use my contract at the same time?
for example:let's say we have seller 1, buyer 1 with price 2 ETH at state 1.
at the same time seller 2, buyer 2 with price 3 ETH at state 0.
each one of them is using the contract at the same time and they can view their contract details using the contract ID. how I can do that?
I thought about creating a function to set the state to initial state 0,then a new user can use the contract, and retrieve their data from the mapping using contract ID. but I'm not sure if this is the best practice. Can anyone advice please!
Thank you in advance.

How can resolve 'Undeclared identifier' during withdraw from smart contract?

I created an array of each address and amount of all users who have previously deposited a certain amount of ETH, then used the 'transfer' function (within : retireMyCoins()) to retrieve the amount and address of the user who is using the contract from the list. The user can then withdraw his ETH.
When compiling the contract, in the last function "retireMyCoins" the console returns the following error: 'Undeclared identifier'.
pragma solidity ^0.4.17;
contract myVault {
address[] public users;
uint[] public totalDeposited;
function sendToken(address user, uint amount) public payable {
require(msg.value > 0.001 ether);
user = msg.sender;
amount = msg.value;
users.push(msg.sender);
totalDeposited.push(msg.value);
}
function getUsers() public view returns (address[]) {
return users;
}
function getAmount() public view returns (uint[]) {
return totalDeposited;
}
function retireMyCoins() public {
require(user[msg.sender]);
require(amount[msg.value]);
user.transfer(this.amount);
}
}
You have to create amount as a store variable in the beginning of your contract. Also, to make it work as you expect, you should map the balance of each user, like the following:
...
mapping( address => uint ) balances;
function sendToken(address user, uint amount) public payable {
balances[msg.sender] = amount;
...
}
and then you can allow the withdrawal:
function retireMyCoins() public {
uint amountToWithdraw = balances[msg.sender]
balances[msg.sender] = 0;
msg.sender.transfer(amountToWithdraw);
}
Remember to zero the user balance before the transfer as above.

How to transfer on truffle develop

I made this contract:
pragma solidity ^0.4.25;
contract MyTransfer {
address owner;
uint data;
uint private amount;
string greeting = "Hello World";
constructor() public {
owner = msg.sender;
}
function greet () constant public returns (string) {
return greeting;
}
function deposit() public payable {
amount += msg.value;
}
function withdraw() public {
msg.sender.transfer(amount);
}
function kill () public {
require(owner == msg.sender);
selfdestruct(owner);
}
}
Compile and deploy successfully finished.
Then on truffle develop console.
mt = MyTransfer.at(MyTransfer.address);
>mt.greet();
works
>mt.deposit(1);
Error: Invalid number of arguments to Solidity function
How can I make transfer on truffle console?
It is not working because your deposit() function is not waiting for any params. You need to send some value with your transaction in order for it to work. Try this:
mt.deposit({value: 'the amount of ether you want to send'});

How to declare a listed variable in solidity?

I've created a function in solidity smart contract that add players in a game, the players should be stored as an "user" or a "hero" as a role in the game. The user send a transaction request while the hero send a reward. I've created a modifier to allow only the user to request and the hero to send a reward, but to define the role of each one of them in the registration phase I'm confused about it. Thanks in advance.
function AddPlayer(string _name, string _role) public returns (bool){
players[msg.sender].name=_name;
players[msg.sender].Paddress=msg.sender;
players[msg.sender].role = _role;
return true;
}
modifier onlyuser() {
require(msg.sender == user, "Only user can call this method");
_;}
modifier onlyheros() {
require(msg.sender == hero, "Only hero can call this method");
_;}
function Request() onlyuser external payable returns(bool) {
balances[msg.sender] += msg.value;
}
function Reward() onlyhero external payable returns (bool) {
balances[msg.sender] += msg.value;
user.transfer(msg.value);
}
Try to declare them as an enum. enum name {variable1, variable2}
You can create a mapping and functions to check user roles like that:
pragma solidity >=0.4.22 <0.6.0;
pragma experimental ABIEncoderV2;
// User address => Role of user
mapping(address => string) UserAuth;
// Set user role to a User Address
function setUser(address _userAddress, string memory _role) public {
UserAuth[_userAddress] = _role;
}
//Check user role
modifier checkAuth(string memory _role){
require(keccak256(abi.encode(UserAuth[msg.sender])) == keccak256(abi.encode(_role)));
_;
}
//get user role
function getUserAuth(address _userAddress) public view returns ( string memory){
return UserAuth[_userAddress];
}
and also you can set an ADMIN user as a constructor to control of the functions like that:
pragma solidity >=0.4.22 <0.6.0;
pragma experimental ABIEncoderV2;
// User address => Role of user
mapping(address => string) UserAuth;
constructor() public{
UserAuth[msg.sender] = "ADMIN";
}
//Check user role
modifier checkAuth(string memory _role){
require(keccak256(abi.encode(UserAuth[msg.sender])) == keccak256(abi.encode(_role)));
_;
}
// Set User Role to a User Address
function setUser(address _userAddress, string memory _role) public checkAuth("ADMIN"){
UserAuth[_userAddress] = _role;
}
// get user role
function getUserAuth(address _userAddress) public view checkAuth("ADMIN") returns ( string memory){
return UserAuth[_userAddress];
}

Check that object is null in solidity mapping

I have this solidity mapping
mapping (string => Ticket) public myMapping;
I want to check if myMapping[key] exists or not. How can I check?
The entire storage space is virtually initialized to 0 (there is no undefined).
So you have to compare the value to the 0 value for your type.
For example, mapping[key] == address(0x0) or mapping[key] = bytes4(0x0).
There is no direct method to check whether the mapping has particular key. But you can check if mapping property has value or not. The following example considered that the Ticket is the struct with some property.
pragma solidity >=0.4.21 <0.6.0;
contract Test {
struct Ticket {
uint seatNumber;
}
mapping (string => Ticket) myMapping;
function isExists(string memory key) public view returns (bool) {
if(myMapping[key].seatNumber != 0){
return true;
}
return false;
}
function add(string memory key, uint seatNumber) public returns (bool){
myMapping[key].seatNumber = seatNumber;
return true;
}
}
pragma solidity ^0.8.0;
contract BookLibNew{
address public owner;
constructor() public{
owner = msg.sender;
}
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
struct bookDet{
uint bookId;
string bookTitle;
string bookAuthor;
}
mapping (uint8 => bookDet) public bookLib;
function addBookLib(uint8 _bookId, string memory _bookTitle, string memory _bookAuthor)
public onlyOwner {
require(bookLib(_bookId) == false, "Error: Book already exists");
bookLib[_bookId].bookTitle = _bookTitle;
bookLib[_bookId].bookAuthor = _bookAuthor;
}
function readBookDetails(uint8 _bookId) public view returns(string memory, string memory){
return(bookLib[_bookId].bookTitle, bookLib[_bookId].bookAuthor);
}
}