Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 39

19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

1. Write a Solidity function to implement a decentralized identity system, where users can prove
their identity without relying on a centralized authority.

// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;

contract IdentitySystem {
    struct Identity {
        string name;
        string email;
        bool verified;
    }
   
    mapping(address => Identity) public identities;
   
    function verifyIdentity(string memory _name, string memory _email) public {
        require(identities[msg.sender].verified == false, "Identity already
verified");
        identities[msg.sender] = Identity(_name, _email, true);
    }
   
    function getIdentity(address _user) public view returns (string memory,
string memory, bool) {
        return (identities[_user].name, identities[_user].email,
identities[_user].verified);
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

2. Write a Solidity function to implement a prediction market, where users can bet on the outcome
of future events.

// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;

contract PredictionMarket {
    enum Outcome { Undecided, Yes, No }
   
    struct Market {
        address creator;
        string question;
        uint256 yesShares;
        uint256 noShares;
        uint256 resolutionTime;
        Outcome outcome;
        bool resolved;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

        mapping(address => uint256) shares;


    }
   
    mapping(uint256 => Market) public markets;
    uint256 public numMarkets = 0;
   
    function createMarket(string memory _question, uint256 _resolutionTime)
public returns (uint256) {
        Market storage market = markets[numMarkets++];
        market.creator = msg.sender;
        market.question = _question;
        market.resolutionTime = _resolutionTime;
        return numMarkets - 1;
    }
   
    function buyShares(uint256 _marketId, uint256 _numShares, Outcome _outcome)
public payable {
        Market storage market = markets[_marketId];
        require(market.resolved == false, "Market already resolved");
        require(msg.value >= _numShares * 1 ether, "Not enough ether");
        require(_outcome == Outcome.Yes || _outcome == Outcome.No, "Invalid
outcome");
       
        if (_outcome == Outcome.Yes) {
            market.yesShares += _numShares;
        } else {
            market.noShares += _numShares;
        }
        market.shares[msg.sender] += _numShares;
    }
   
    function resolveMarket(uint256 _marketId, Outcome _outcome) public {
        Market storage market = markets[_marketId];
        require(market.resolved == false, "Market already resolved");
        require(market.creator == msg.sender, "Only creator can resolve
market");
        require(block.timestamp >= market.resolutionTime, "Resolution time not
reached");
        require(_outcome == Outcome.Yes || _outcome == Outcome.No, "Invalid
outcome");
       
        market.outcome = _outcome;
        market.resolved = true;
    }
   
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

    function claimWinnings(uint256 _marketId) public {


        Market storage market = markets[_marketId];
        require(market.resolved == true, "Market not resolved");
        require(market.shares[msg.sender] > 0, "No shares owned");
       
        uint256 totalShares = market.yesShares + market.noShares;
        uint256 payout = address(this).balance * market.shares[msg.sender] /
totalShares;
       
        if (market.outcome == Outcome.Yes) {
            payable(msg.sender).transfer(payout);
        }
       
        market.shares[msg.sender] = 0;
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

3. Write a Solidity function to implement a supply chain management system, where products can
be tracked from creation to delivery.
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;

contract SupplyChain {
    struct BasicProductInfo {
        string name;
        string description;
        uint256 quantity;
        uint256 price;
        uint256 creationTime;
    }
   
    struct ShippingInfo {
        bool shipped;
        uint256 shippingTime;
        bool delivered;
        uint256 deliveryTime;
        address carrier;
        address recipient;
    }
   
    struct Product {
        uint256 productId;
        address creator;
        BasicProductInfo basicInfo;
        ShippingInfo shippingInfo;
    }
   
    mapping(uint256 => Product) public products;
    uint256 public numProducts = 0;
   
    function createProduct(string memory _name, string memory _description,
uint256 _quantity, uint256 _price) public returns (uint256) {
        BasicProductInfo memory basicInfo = BasicProductInfo(_name,
_description, _quantity, _price, block.timestamp);
        ShippingInfo memory shippingInfo;
        Product storage product = products[numProducts++];
        product.productId = numProducts - 1;
        product.creator = msg.sender;
        product.basicInfo = basicInfo;
        product.shippingInfo = shippingInfo;
        return numProducts - 1;
    }
   
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

    function shipProduct(uint256 _productId, address _carrier) public {


        Product storage product = products[_productId];
        require(product.shippingInfo.shipped == false, "Product already
shipped");
        require(product.creator == msg.sender, "Only creator can ship
product");
       
        product.shippingInfo.shipped = true;
        product.shippingInfo.shippingTime = block.timestamp;
        product.shippingInfo.carrier = _carrier;
    }
   
    function receiveProduct(uint256 _productId) public {
        Product storage product = products[_productId];
        require(product.shippingInfo.delivered == false, "Product already
delivered");
        require(product.shippingInfo.carrier == msg.sender, "Only carrier can
deliver product");
       
        product.shippingInfo.delivered = true;
        product.shippingInfo.deliveryTime = block.timestamp;
    }
   
    function getProduct(uint256 _productId) public view returns (string
memory, string memory, uint256, uint256, uint256, bool, bool) {
        Product storage product = products[_productId];
        return (product.basicInfo.name, product.basicInfo.description,
product.basicInfo.quantity, product.basicInfo.price,
product.basicInfo.creationTime, product.shippingInfo.shipped,
product.shippingInfo.delivered);
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

4. Write a Solidity function to implement a decentralized autonomous organization (DAO), where


users can vote on governance decisions.

// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;


import "@openzeppelin/contracts/access/Ownable.sol";

contract DAO is Ownable {


19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

    struct Proposal {
        uint256 id;
        string description;
        uint256 voteYes;
        uint256 voteNo;
        bool executed;
    }

    mapping(uint256 => Proposal) public proposals;


    uint256 public numProposals = 0;
    mapping(address => bool) public members;
    uint256 public quorum;

    constructor(uint256 _quorum) {
        quorum = _quorum; // Minimum number of people for voting
    }
   
    function addMember(address _member) public onlyOwner {
        members[_member] = false;
    }

    function createProposal(string memory _description) public onlyOwner {


        proposals[numProposals++] = Proposal(numProposals, _description, 0,
0, false);
    }

    function vote(uint256 _proposalId, bool _vote) public {


        require(members[msg.sender] == false, "Already voted");
        Proposal storage proposal = proposals[_proposalId];
        require(!proposal.executed, "Proposal already executed");
        if (_vote) {
            proposal.voteYes++;
        } else {
            proposal.voteNo++;
        }
        members[msg.sender] = true;
    }

    function executeProposal(uint256 _proposalId) public {


        Proposal storage proposal = proposals[_proposalId];
        require(!proposal.executed, "Proposal already executed");
        require(proposal.voteYes > quorum, "Quorum not reached");
        proposal.executed = true;
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

5. Write a Solidity function to implement a smart contract insurance policy, where users can be
compensated for losses that meet certain conditions.

// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;

contract InsurancePolicy {
    struct Policies {
        bool isDead;
        bool accident;
        bool hasFamily;
    }
   
    mapping(address => uint256) public policyholders; // mapping of
policyholders and their policy amounts
    uint256 public premium; // the premium that must be paid to purchase the
policy
    uint256 public payoutAmount; // the amount to be paid out if the policy
conditions are met
    uint256 public policyExpiration; // the expiration date of the policy
    mapping(address => Policies) public policyholdersPolicies; // Policies of
Insurance for every policy holder

   
    constructor(uint256 _premium, uint256 _payoutAmount, uint256
_policyDurationDays) {
        premium = _premium;
        payoutAmount = _payoutAmount;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

        policyExpiration = block.timestamp + (_policyDurationDays * 1 days);


// convert policy duration to seconds
    }

    function purchasePolicy() public payable {


        require(msg.value >= premium, "Premium amount not met.");
        require(block.timestamp < policyExpiration, "Policy expired.");

        policyholders[msg.sender] = msg.value; // add policyholder to mapping


    }

    function updatePolicies(bool _isDead, bool _accident, bool _hasFamily)


public
    {
        policyholdersPolicies[msg.sender] = Policies(_isDead, _accident,
_hasFamily);
    }

    function fileClaim() public {


        require(policyholders[msg.sender] > 0, "No policy found for
sender.");
        require(block.timestamp < policyExpiration, "Policy expired.");

        // Perform checks to determine if policy conditions are met


        // If conditions are met, transfer payout amount to policyholder
        Policies storage _policies = policyholdersPolicies[msg.sender];
        if (_policies.isDead && _policies.accident && _policies.hasFamily) {
            payable(msg.sender).transfer(payoutAmount);
        }
    }

    function cancelPolicy() public {


        require(policyholders[msg.sender] > 0, "No policy found for
sender.");
        require(block.timestamp < policyExpiration, "Policy expired.");

        // Refund policy amount to policyholder


        payable(msg.sender).transfer(policyholders[msg.sender]);
        policyholders[msg.sender] = 0; // remove policyholder from mapping
    }

    function extendPolicy(uint256 _policyDurationDays) public {


        require(policyholders[msg.sender] > 0, "No policy found for
sender.");
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

        // Add additional days to policy expiration date


        policyExpiration += _policyDurationDays * 1 days;
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

6. Write a Solidity function to implement a token swap, where one ERC-20 token can be exchanged
for another.

// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;


import "./ERC20.sol";

contract TokenSwap {
    UserToken public tokenA;
    UserToken public tokenB;

    constructor(UserToken _tokenA, UserToken _tokenB) {


        tokenA = _tokenA;
        tokenB = _tokenB;
    }
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

    function swapTokens(uint256 amount) public {


        require(amount > 0, "Amount must be greater than 0");
        require(tokenA.balanceOf(msg.sender) >= amount, "Insufficient
balance");

        // Approve the TokenSwap contract to spend the amount of TokenA being


swapped
        tokenA.approve(address(this), amount);

        // Transfer the TokenA to the TokenSwap contract


        tokenA.transferFrom(msg.sender, address(this), amount);

        // Calculate the amount of TokenB to be received based on the swap


rate
        uint256 swapRate = getSwapRate();
        uint256 receivedAmount = amount * swapRate;

        // Transfer the TokenB to the user


        tokenB.transfer(msg.sender, receivedAmount);
    }

    function getSwapRate() public pure returns (uint256) {


        // return the swap rate calculation based on market conditions
        return 100;
    }
}

7. Write a Solidity function to implement a token vesting contract, where tokens are gradually
released over a period of time.

// SPDX-License-Identifier: MIT License


// Vesting: process of giving an employee ownership of something, like stock
options or retirement benefits
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

contract TokenVesting {
    using SafeMath for uint256;

    address public beneficiary;


    uint256 public cliff;
    uint256 public start;
    uint256 public duration;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

    bool public revocable;

    mapping(address => uint256) public released;


    mapping(address => bool) public revoked;

    IERC20 public token;

    event Released(address indexed tokenHolder, uint256 amount);


    event Revoked(address indexed tokenHolder);

    constructor(
        address _beneficiary,
        uint256 _cliffDuration,
        uint256 _start,
        uint256 _duration,
        bool _revocable,
        address _token
    ) {
        require(_beneficiary != address(0), "Invalid beneficiary address");
        require(_start.add(block.timestamp+_duration) > block.timestamp,
"Invalid duration");
        require(_token != address(0), "Invalid token address");

        beneficiary = _beneficiary;
        revocable = _revocable;
        token = IERC20(_token);
        start = _start;
        cliff = _start.add(_cliffDuration);
        duration = _duration;
    }

    function release() public {


        uint256 unreleased = releasableAmount();
        require(unreleased > 0, "No tokens to release");

        released[msg.sender] = released[msg.sender].add(unreleased);
        token.transfer(msg.sender, unreleased);

        emit Released(msg.sender, unreleased);


    }

    function revoke() public {


        require(revocable, "Contract is not revocable");
        require(!revoked[msg.sender], "Tokens already revoked");
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

        uint256 balance = token.balanceOf(address(this));


        uint256 unreleased = releasableAmount();
        uint256 refund = balance.sub(unreleased);

        revoked[msg.sender] = true;
        released[msg.sender] = 0;

        if (refund > 0) {
            token.transfer(msg.sender, refund);
        }

        emit Revoked(msg.sender);
    }

    function releasableAmount() public view returns (uint256) {


        return vestedAmount().sub(released[msg.sender]);
    }

    function vestedAmount() public view returns (uint256) {


        uint256 currentBalance = token.balanceOf(address(this));
        uint256 totalBalance = currentBalance.add(released[msg.sender]);

        if (block.timestamp < cliff) {


            return 0;
        } else if (block.timestamp >= start.add(duration) ||
revoked[msg.sender]) {
            return totalBalance;
        } else {
            return
totalBalance.mul(block.timestamp.sub(start)).div(duration);
        }
    }
}

8. Write a Solidity function to implement a gasless transfer, where tokens can be transferred
without requiring the user to pay for gas.

// SPDX-License-Identifier: MIT License


pragma solidity ^0.8.0;
import "./ERC20.sol";

contract GaslessTransfer {
    function transfer(
        address tokenAddress,
        address recipient,
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

        uint256 amount
    ) public payable {
        // Transfer the tokens
        ERC20 token = ERC20(tokenAddress);
        require(token.allowance(msg.sender, address(this)) >= amount,
"Insufficient allowance");
        require(token.transferFrom(msg.sender, recipient, amount), "Transfer
failed");
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

9. Write a Solidity function to implement a stablecoin contract, where the value of the token is
pegged to a stable asset such as the US dollar.

pragma solidity ^0.8.0;

contract USDT {
    string public name = "USD Tether";
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

    string public symbol = "USDT";


    uint8 public decimals = 18;
    uint256 public totalSupply;
    address public owner;
    mapping(address => uint256) public balanceOf;
   
    event Transfer(address indexed from, address indexed to, uint256 value);
   
    constructor() {
        totalSupply = 0;
        owner = msg.sender;
    }
   
    function mint(address to, uint256 amount) public {
        require(msg.sender == owner, "Only the owner can mint USDT");
        balanceOf[to] += amount;
        totalSupply += amount;
        emit Transfer(address(0), to, amount);
    }
   
    function burn(address from, uint256 amount) public {
        require(msg.sender == owner, "Only the owner can burn USDT");
        require(balanceOf[from] >= amount, "Insufficient balance");
        balanceOf[from] -= amount;
        totalSupply -= amount;
        emit Transfer(from, address(0), amount);
    }
   
    function transfer(address to, uint256 amount) public {
        require(balanceOf[msg.sender] >= amount, "Insufficient balance");
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
        emit Transfer(msg.sender, to, amount);
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

10. Write a Solidity function to implement a prediction market for sports events, where users can
bet on the outcome of games and matches.

// SPDX-License-Identifier: MIT License


pragma solidity ^0.8.0;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

contract SportsPredictionMarket {
   
    struct Bet {
        address payable bettor;
        uint256 amount;
        bool outcome;
    }
   
    address public owner;
    uint256 public totalPool;
    uint256 public endTime;
    uint256 public winningOutcome;
    bool public marketEnded;
    mapping(bool => uint256) public outcomePools;
    mapping(address => Bet) public bets;
   
    constructor(uint256 _endTime) {
        owner = msg.sender;
        endTime = block.timestamp + _endTime;
    }
   
    function bet(bool _outcome) public payable {
        require(block.timestamp < endTime, "Betting period has ended");
        require(msg.value > 0, "Bet amount must be greater than 0");
        require(!marketEnded, "Market has already ended");
        Bet storage betInfo = bets[msg.sender];
        require(betInfo.amount == 0, "You have already placed a bet");
        betInfo.bettor = payable(msg.sender);
        betInfo.amount = msg.value;
        betInfo.outcome = _outcome;
        outcomePools[_outcome] += msg.value;
        totalPool += msg.value;
    }
   
    function endMarket(uint256 _winningOutcome) public {
        require(msg.sender == owner, "Only the owner can end the market");
        require(block.timestamp >= endTime, "Betting period has not ended
yet");
        require(!marketEnded, "Market has already ended");
        winningOutcome = _winningOutcome;
        marketEnded = true;
    }
   
    function withdraw() public {
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

        Bet memory betInfo = bets[msg.sender];


        require(betInfo.amount > 0, "You have not placed a bet");
        require(marketEnded, "Market has not ended yet");
        uint256 payout = 0;
        if (betInfo.outcome == true) {
            payout = (betInfo.amount * totalPool) /
outcomePools[betInfo.outcome];
            betInfo.bettor.transfer(payout);
        }
        bets[msg.sender] = Bet(payable(address(0)), 0, false);
    }
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

11. Explain all the terms on the following link with example.
https://docs.soliditylang.org/en/v0.8.19/cheatsheet.html

Modifiers
pure  for functions: Disallows modification or access of state.

function add(uint256 x, uint256 y) pure public returns (uint256) {

return x + y;
}

view  for functions: Disallows modification of state.

function balanceOf(address account) view public returns (uint256) {

return balances[account];
}

payable  for functions: Allows them to receive Ether together with a call.

function buyTokens() payable public {

require(msg.value > 0);

uint256 amount = msg.value * exchangeRate;

balances[msg.sender] += amount;
}

constant  for state variables: Disallows assignment (except initialisation), does not occupy
storage slot.

contract MyContract {

uint256 constant MAX_SUPPLY = 1000000;


}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

immutable  for state variables: Allows exactly one assignment at construction time and is
constant afterwards. Is stored in code.

contract MyContract {

address immutable OWNER;

constructor() {

OWNER = msg.sender;

}
}

anonymous  for events: Does not store event signature as topic.


event Transfer(address indexed from, address indexed to, uint256 value);

indexed  for event parameters: Stores the parameter as topic.


event Transfer(address indexed from, address indexed to, uint256 value);

virtual  for functions and modifiers: Allows the function’s or modifier’s behaviour to be
changed in derived contracts.

contract Base {

function foo() virtual public { }

contract Derived is Base {

function foo() public override { }


}

override : States that this function, modifier or public state variable changes the
behaviour of a function or modifier in a base contract.

contract Base {
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

function foo() virtual public { }

contract Derived is Base {

function foo() public override { }


}

Function Visibility Specifiers


public : visible externally and internally (creates a getter function for storage/state
variables)

contract VisibilityExample {

uint public myNumber;

function setNumber(uint _number) public {

myNumber = _number;

function getNumber() public view returns (uint) {

return myNumber;

}
}
private : only visible in the current contract

contract VisibilityExample {

uint private myNumber;


19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

function setNumber(uint _number) private {

myNumber = _number;

function getNumber() public view returns (uint) {

return myNumber;

}
}
external : only visible externally (only for functions) - i.e. can only be message-called
(via  this.func )

contract VisibilityExample {

function myFunction() external pure returns (string memory) {

return "Hello, World!";

}
}
internal : only visible internally

contract VisibilityExample {

uint internal myNumber;

function setNumber(uint _number) internal {

myNumber = _number;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

function getNumber() public view returns (uint) {

return myNumber;

contract ChildContract is VisibilityExample {

function doSomething() public {

setNumber(42);

}
}

Type Information
type(C).name  ( string ): the name of the contract

contract MyContract {

function getName() external view returns (string memory) {

return type(MyContract).name;

}
}
type(C).creationCode  ( bytes memory ): creation bytecode of the given contract, see Type
Information.
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

contract MyContract {

function getCreationCode() external view returns (bytes memory) {

return type(MyContract).creationCode;

}
}
type(C).runtimeCode  ( bytes memory ): runtime bytecode of the given contract, see Type
Information.

contract MyContract {

function getRuntimeCode() external view returns (bytes memory) {

return type(MyContract).runtimeCode;

}
}
type(I).interfaceId  ( bytes4 ): value containing the EIP-165 interface identifier of the
given interface, see Type Information.

interface MyInterface {

function getInterfaceId() external pure returns (bytes4) {

return type(MyInterface).interfaceId;

}
}
type(T).min  ( T ): the minimum value representable by the integer type  T , see Type
Information.

contract MyContract {

function getMinUint8() external pure returns (uint8) {

return type(uint8).min;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

}
}
type(T).max  ( T ): the maximum value representable by the integer type  T , see Type
Information.

contract MyContract {

function getMaxUint8() external pure returns (uint8) {

return type(uint8).max;

}
}
Contract-related
this  (current contract’s type): the current contract, explicitly convertible
to  address  or  address payable

pragma solidity ^0.8.0;

contract MyContract {

function getContractAddress() public view returns(address) {

return address(this); // returns the address of the current contract

}
}
super : a contract one level higher in the inheritance hierarchy

pragma solidity ^0.8.0;

contract A {
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

uint256 public x;

constructor(uint256 _x) {

x = _x;

contract B is A {

constructor(uint256 _x, uint256 _y) A(_x) {

super.x += _y; // adds _y to the value of x in contract A

}
}
selfdestruct(address payable recipient) : destroy the current contract, sending its funds to
the given address

pragma solidity ^0.8.0;

contract MyContract {

address payable public owner;

constructor() {

owner = payable(msg.sender);

}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

function close() public {

selfdestruct(owner); // destroys the contract and sends its funds to the owner
address

}
}

Mathematical and Cryptographic Functions


keccak256(bytes memory) returns (bytes32) : compute the Keccak-256 hash of the input
bytes32 hash = keccak256(abi.encodePacked("Hello, world!"));
sha256(bytes memory) returns (bytes32) : compute the SHA-256 hash of the input

bytes32 hash = sha256(abi.encodePacked("Hello, world!"));


ripemd160(bytes memory) returns (bytes20) : compute the RIPEMD-160 hash of the input

bytes20 hash = ripemd160(abi.encodePacked("Hello, world!"));


ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address) : recover address
associated with the public key from elliptic curve signature, return zero on error

function recoverAddress(

bytes32 hash,

uint8 v,

bytes32 r,

bytes32 s

) public pure returns (address) {

return ecrecover(hash, v, r, s);


}
: compute  (x + y) % k  where the addition is
addmod(uint x, uint y, uint k) returns (uint)

performed with arbitrary precision and does not wrap around at  2**256 . Assert that  k !
= 0  starting from version 0.5.0.
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

uint result = addmod(10, 20, 7); // result is 3


mulmod(uint x, uint y, uint k) returns (uint) : compute  (x * y) % k  where the

multiplication is performed with arbitrary precision and does not wrap around at  2**256 .
Assert that  k != 0  starting from version 0.5.0.
uint result = mulmod(10, 20, 7); // result is 6

Validations and Assertions


assert(bool condition) : abort execution and revert state changes if condition
is  false  (use for internal error)

function divide(uint a, uint b) public pure returns (uint) {

assert(b != 0);

return a / b;
}
require(bool condition) : abort execution and revert state changes if condition
is  false  (use for malformed input or error in external component)
require(bool condition, string memory message) : abort execution and revert state changes if

condition is  false  (use for malformed input or error in external component). Also provide
error message.

function withdraw(uint amount) public {

require(amount <= balances[msg.sender], "Insufficient balance");

msg.sender.transfer(amount);

balances[msg.sender] -= amount;
}
revert() : abort execution and revert state changes
revert(string memory message) : abort execution and revert state changes providing an

explanatory string

function register(string memory name) public {


19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

if (bytes(name).length == 0) {

revert("Name cannot be empty");

// continue with registration


}

Block and Transaction Properties


blockhash(uint blockNumber) returns (bytes32) : hash of the given block - only works for 256
most recent blocks
// Using blockhash to get the hash of the previous block

bytes32 previousBlockHash = blockhash(block.number - 1);


block.basefee  ( uint ): current block’s base fee (EIP-3198 and EIP-1559)

block.chainid  ( uint ): current chain id


block.coinbase  ( address payable ): current block miner’s address

block.difficulty  ( uint ): current block difficulty ( EVM < Paris ). For other EVM versions it

behaves as a deprecated alias for  block.prevrandao  that will be removed in the next
breaking release
block.gaslimit  ( uint ): current block gaslimit

block.number  ( uint ): current block number

block.prevrandao  ( uint ): random number provided by the beacon chain ( EVM >= Paris )

(see EIP-4399 )
block.timestamp  ( uint ): current block timestamp in seconds since Unix epoch

gasleft() returns (uint256) : remaining gas

msg.data  ( bytes ): complete calldata

msg.sender  ( address ): sender of the message (current call)

function onlyOwner() public {

require(msg.sender == owner, "Only the contract owner can call this function");

// function code...
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

}
msg.sig  ( bytes4 ): first four bytes of the calldata (i.e. function identifier)
msg.value  ( uint ): number of wei sent with the message

tx.gasprice  ( uint ): gas price of the transaction

function expensiveFunction() public {

uint256 gasStart = gasleft();

// function code that consumes gas...

uint256 gasSpent = gasStart - gasleft();

require(gasSpent < 50000, "Function gas cost too high");


}
tx.origin  ( address ): sender of the transaction (full call chain)

function onlyOwner() public {

require(tx.origin == owner, "Only the contract owner can initiate transactions");

// function code...
}
Members of  address

address myAddress = 0x1234567890123456789012345678901234567890;


<address>.balance  ( uint256 ): balance of the Address in Wei

// Get balance of an address


uint256 myBalance = myAddress.balance;

<address>.code  ( bytes memory ): code at the Address (can be empty)

// Get code at an address


bytes memory myCode = myAddress.code;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

<address>.codehash  ( bytes32 ): the codehash of the Address

// Get code at an address


bytes memory myCode = myAddress.code;

<address payable>.send(uint256 amount) returns (bool) : send given amount of Wei


to Address, returns  false  on failure

// Send ether to an address using send()

bool sent = payable(myAddress).send(1000 wei);

if (!sent) {

// handle failure
}
<address payable>.transfer(uint256 amount) : send given amount of Wei to Address, throws
on failure

// Send ether to an address using transfer()


payable(myAddress).transfer(1000 wei);

Members of  bytes  and  string

bytes.concat(...) returns (bytes memory) : Concatenates variable number of arguments to


one byte array

// bytes.concat() example

bytes memory a = hex"001122";

bytes memory b = hex"334455";

bytes memory c = bytes.concat(a, b);


// c now contains hex"001122334455"
string.concat(...) returns (string memory) : Concatenates variable number of arguments to
one string array
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

// string.concat() example

string memory name = "John";

string memory surname = "Doe";

string memory fullName = string.concat(name, " ", surname);


// fullName now contains "John Doe"

ABI Encoding and Decoding Functions


abi.decode(bytes memory encodedData, (...)) returns (...) : ABI-decodes the provided data.
The types are given in parentheses as second argument.
Example:  (uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], byte
s))

bytes memory encodedData = abi.encodeWithSignature("transfer(address,uint256)",


recipient, amount);
(uint a, uint[2] memory b, bytes memory c) = abi.decode(encodedData, (uint, uint[2],
bytes));
abi.encode(...) returns (bytes memory) : ABI-encodes the given arguments

bytes memory encodedData = abi.encode(recipient, amount);


abi.encodePacked(...) returns (bytes memory) : Performs packed encoding of the given

arguments. Note that this encoding can be ambiguous!


bytes memory packedData = abi.encodePacked(recipient, amount);
abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory) : ABI-encodes the given

arguments starting from the second and prepends the given four-byte selector
bytes memory encodedData =
abi.encodeWithSelector(bytes4(keccak256(bytes("transfer(address,uint256)"))), recipient,
amount);
abi.encodeCall(function functionPointer, (...)) returns (bytes memory) : ABI-encodes a call

to  functionPointer  with the arguments found in the tuple. Performs a full type-check,
ensuring the types match the function signature. Result
equals  abi.encodeWithSelector(functionPointer.selector, (...))

function transfer(address recipient, uint256 amount) external returns (bool) {


19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3

bytes memory encodedData = abi.encodeCall(transfer.selector, recipient, amount);

// ...
}
abi.encodeWithSignature(string memory signature, ...) returns (bytes memory) : Equivalent
to  abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)
bytes memory encodedData = abi.encodeWithSignature("transfer(address,uint256)",
recipient, amount);

You might also like