DEV Community

ASHDEEP SINGH
ASHDEEP SINGH

Posted on

A simple wallet in solidity

Hi there folks.
This week of learning blockchain was well spent in learning about wallet and implementing it.

Here is what my friend ChatGPT says about wallet
In the context of blockchain and cryptocurrencies, a wallet is a digital tool that allows users to store, manage, and interact with their cryptocurrencies. A wallet is essential for sending, receiving, and managing digital assets on a blockchain.

Before moving on to our own wallet let us first understand a few important terms.

Payable

A payable function in Solidity is a function that can receive Ether. Functions marked as payable can process and store the Ether sent to them during their invocation.

Example:

pragma solidity ^0.8.0;

contract PayableExample {
    // Function to receive Ether. The function is called when Ether is sent to the contract address.
    receive() external payable {}

    // Payable function to receive Ether and perform additional logic
    function deposit() external payable {
        // You can access the amount of Ether sent with msg.value
    }

    // Function to check the balance of the contract
    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}
Enter fullscreen mode Exit fullscreen mode

Events and Emit

Events in Solidity are a way to log information on the blockchain. They are mainly used to communicate with the outside world and are cheap to store compared to storing data in state variables.

Example:

pragma solidity ^0.8.0;

contract EventExample {
    // Declare an event
    event Deposited(address indexed from, uint amount);

    // Emit the event within a payable function
    function deposit() external payable {
        emit Deposited(msg.sender, msg.value);
    }
}
Enter fullscreen mode Exit fullscreen mode

msg.value

msg.value is a special global variable in Solidity that holds the amount of Ether (in wei) sent along with a function call.

Example:

pragma solidity ^0.8.0;

contract MsgValueExample {
    // Payable function to receive Ether and access msg.value
    function deposit() external payable {
        require(msg.value > 0, "Must send some Ether");
    }
}
Enter fullscreen mode Exit fullscreen mode

Transfer Function

The transfer function is used to send Ether from a contract to an external address. It forwards 2300 gas to the recipient, preventing reentrancy attacks by limiting the gas available to the recipient's fallback function.

Example:

pragma solidity ^0.8.0;

contract TransferExample {
    address payable public recipient;

    constructor(address payable _recipient) {
        recipient = _recipient;
    }

    // Function to send Ether to the recipient
    function sendEther() external payable {
        recipient.transfer(msg.value);
    }
}
Enter fullscreen mode Exit fullscreen mode

Fallback and Receive Functions

Fallback and receive functions are special functions in Solidity used to handle Ether transfers and direct calls to the contract that do not match any function signature.

Receive Function: Triggered when a contract is sent Ether without data.
Fallback Function: Triggered when a contract is sent Ether with data or when no other function matches the call.

Example:

pragma solidity ^0.8.0;

contract FallbackReceiveExample {
    event Received(address sender, uint amount);

    // Receive function to handle Ether sent to the contract
    receive() external payable {
        emit Received(msg.sender, msg.value);
    }

    // Fallback function to handle non-matching calls and Ether with data
    fallback() external payable {
        emit Received(msg.sender, msg.value);
    }
}
Enter fullscreen mode Exit fullscreen mode

Library

A library in Solidity is a way to deploy reusable code that can be called by other contracts. Libraries cannot hold state and cannot send Ether. They are useful for code reuse and avoiding code duplication.

Example:

pragma solidity ^0.8.0;

// Define a library
library MathLibrary {
    function add(uint a, uint b) internal pure returns (uint) {
        return a + b;
    }

    function subtract(uint a, uint b) internal pure returns (uint) {
        require(b <= a, "Subtraction overflow");
        return a - b;
    }
}

contract LibraryExample {
    using MathLibrary for uint;

    function addNumbers(uint a, uint b) public pure returns (uint) {
        return a.add(b);
    }

    function subtractNumbers(uint a, uint b) public pure returns (uint) {
        return a.subtract(b);
    }
}
Enter fullscreen mode Exit fullscreen mode

Now finally the good part let us move on to our wallet.

Overview

This Solidity contract implements a simple wallet with features for transferring Ether, handling transactions, managing ownership, and providing emergency functions.

Main Components:

State Variables:

  • Transaction[] public transactionHistory; Stores the history of transactions.

  • address public owner; The owner of the contract.

  • string public str; A public string variable (not used in the provided code).

  • bool public stop; Flag to indicate if the contract is in an emergency state.

  • mapping(address => uint) suspiciousUser; Tracks suspicious activities of users.

Events:

  • event Transfer(address receiver, uint amount);
  • event Receive(address sender, uint amount);
  • event ReceiveUser(address sender, address receiver, uint amount); These events are used to log information about transfers and receipts of Ether.

Modifiers:

  • onlyOwner(): Restricts access to the owner of the contract.

  • getSuspiciousUser(address _sender): Restricts access based on the user's suspicious activity count.

  • isEmergencyDeclared(): Restricts access if an emergency is declared.

Functions:

  • constructor(): Sets the contract deployer as the owner.
  • toggleStop(): Toggles the stop state, used for emergency status.
  • changeOwner(address newOwner): Changes the owner of the contract.
  • transferToContract(uint _startTime): Transfers Ether to the contract and records the transaction.
  • transferToUserViaContract(address payable _to, uint _weiAmount): Transfers Ether from the contract to a specified user.
  • withdrawFromContract(uint _weiAmount): Allows the owner to withdraw Ether from the contract.
  • getContractBalanceInWei(): Returns the contract's Ether balance.
  • transferToUserViaMsgValue(address _to): Transfers Ether from the sender to a specified user.
  • receiveFromUser(): Allows a user to send Ether to the owner.
  • getOwnerBalanceInWei(): Returns the owner's Ether balance.
  • receive() external payable: Fallback function to receive Ether and record the transaction.
  • fallback() external: Fallback function to handle non-matching calls and mark suspicious activity.
  • getTransactionHistory(): Returns the history of transactions.
  • emergencyWithdrawl(): Allows the owner to withdraw all Ether in case of an emergency.

Putting everything together the end product looks like this.

[https://github.com/Ashdeep-Singh-97/Blockchain/blob/main/Simple%20Wallet%20Solidity]

That's all folks.
Hope you liked reading it.
Stay tuned in for more....

Top comments (0)