0% found this document useful (0 votes)
41 views30 pages

19f0217 8B Assignment2&3

The Solidity code implements a decentralized identity system where users can store their identity on-chain without relying on a centralized authority. The code defines a struct to store a user's identity details and mappings to save identities by address. Functions allow a user to store their identity and for anyone to verify a user's identity by address.

Uploaded by

Shahid Imran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views30 pages

19f0217 8B Assignment2&3

The Solidity code implements a decentralized identity system where users can store their identity on-chain without relying on a centralized authority. The code defines a struct to store a user's identity details and mappings to save identities by address. Functions allow a user to store their identity and for anyone to verify a user's identity by address.

Uploaded by

Shahid Imran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 30

Q1: Write a Solidity function to implement a decentralized identity system, where users can prove

their identity without relying on a centralized authority.


Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
contract Q1_0217 {
    struct Identity {
        string name;
        string email;
    }
   
    mapping(address => Identity) private users;
   
    function storeIdentity(string memory name, string memory email) public {
        users[msg.sender] = Identity(name, email);
    }
   
    function verifyIdentity(address user) public view returns (string memory,
string memory) {
        return (users[user].name, users[user].email);
    }
}

Output:
Q2: Write a Solidity function to implement a prediction market, where users can bet on the
outcome of future events.
Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
import "hardhat/console.sol";
contract PredictionMarket {
    struct Market {
        address creator;
        string mission;
        uint256 posShares;
        uint256 negShares;
        uint256 completitionTime;
        bool outcome;
        bool timeHasGone;
        mapping(address => uint256) bidings;
        mapping(address => bool) bidOn;
    }
    mapping(uint256 => Market) public markets;
    uint256 private totalMarkets = 0;
    function setMarket(string memory missionString, uint256 completionTime)
public returns (uint256) {
        Market storage market = markets[totalMarkets++];
        market.creator = msg.sender;
        market.mission = missionString;
        market.completitionTime = completionTime;
        return totalMarkets - 1;
    }
    function bidingOnMissionStatement(uint256 marketIndex, uint256 numShares,
bool outcome) public payable {
        Market storage market = markets[marketIndex];
        require(market.timeHasGone == false, "Time has passed for the mission
to do biding.");
        require(numShares * 1 ether > 0, "too little shares");
        if (outcome == true) {
            market.posShares += numShares;
            market.bidOn[msg.sender]=true;
        } else {
            market.negShares += numShares;
            market.bidOn[msg.sender]=false;
        }
        market.bidings[msg.sender] += numShares;
    }  
    function setMissionStatus(uint256 marketIndex, bool outcome) public {
        Market storage market = markets[marketIndex];
        require(market.timeHasGone == false, "Time has passed for the mission
to set status");
        require(market.creator == msg.sender, "Only creator can set status of
mission");
        require(block.timestamp >= market.completitionTime, "Resolution time
not reached");
        market.outcome = outcome;
        market.timeHasGone = true;
    }   
    function claimWinnings(uint256 marketIndex) public {
        Market storage market = markets[marketIndex];
        require(market.timeHasGone == true, "Time hasn't passed for the
mission status");
        require(market.bidings[msg.sender] > 0, "No winings owned");
       
        uint256 totalShares = market.posShares + market.negShares;
        uint256 payout = address(this).balance * market.bidings[msg.sender] /
totalShares;
       
        if (market.outcome == true && market.bidOn[msg.sender]==true) {
            payable(msg.sender).transfer(payout);
        }
        else if(market.outcome==false && market.bidOn[msg.sender]==false){
            payable(msg.sender).transfer(payout);
        }
        else{
            console.log("no winings, bad luck!");
        }
        market.bidings[msg.sender] = 0;
    }
}
Output:
Q3: Write a Solidity function to implement a supply chain management system, where products
can be tracked from creation to delivery.
Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
contract SupplyChain {
    struct ProductInfo {
        string name;
        string description;
        uint256 quantity;
        uint256 price;
    }   
    struct ShipInfo {
        uint256 shippingTime;
        uint256 deliveryTime;
        address carrier;
        address recipient;
        bool shipped;
        bool delivered;
    }   
    struct Product {
        uint256 productId;
        address creator;
        ProductInfo basicInfo;
        ShipInfo shippingInfo;
    }   
    mapping(uint256 => Product) private products;
    uint256 private totalProducts = 0;   
    function createProduct(string memory name, string memory description,
uint256 quantity, uint256 price) public returns (uint256) {
        ProductInfo memory basicInfo = ProductInfo(name, description,
quantity, price);
        ShipInfo memory shippingInfo;
        Product storage product = products[totalProducts++];
        product.productId = totalProducts - 1;
        product.creator = msg.sender;
        product.basicInfo = basicInfo;
        product.shippingInfo = shippingInfo;
        return totalProducts - 1;
    }   
    function shipProduct(uint256 productIndex, address carrier) public {
        Product storage product = products[productIndex];
        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 receivingProduct(uint256 productIndex) public {
        Product storage product = products[productIndex];
        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 productIndex) public view returns (string
memory, string memory, uint256, uint256, bool, bool) {
        Product storage product = products[productIndex];
        return (product.basicInfo.name, product.basicInfo.description,
product.basicInfo.quantity, product.basicInfo.price,
product.shippingInfo.shipped, product.shippingInfo.delivered);
    }
}
Output:
Q4: Write a Solidity function to implement a decentralized autonomous organization (DAO), where
users can vote on governance decisions.
Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
contract DAO  {
    struct Proposal {
        uint256 id;
        string description;
        uint256 voteYes;
        uint256 voteNo;
        bool executed;
    }
    mapping(uint256 => Proposal) public proposals;
    uint256 private totalProposals = 0;
    mapping(address => bool) public members;
    uint256 private minMembers;
    address private Owner;
    constructor(uint256 minmembers) {
        Owner=msg.sender;
        minMembers = minmembers;
    }   
    function addMember(address member) public {
        require(address(msg.sender)==Owner,"Only Owner can add members");
        members[member] = false;
    }
    function createProposal(string memory description) public {
        require(address(msg.sender)==Owner,"Only Owner can create Proposal");
        proposals[totalProposals++] = Proposal(totalProposals, description, 0,
0, false);
    }
    function vote(uint256 proposalIndex, bool vote) public {
        require(members[msg.sender] == false, "Already voted");
        Proposal storage proposal = proposals[proposalIndex];
        require(!proposal.executed, "Proposal already executed");
        if (vote) {
            proposal.voteYes++;
        } else {
            proposal.voteNo++;
        }
        members[msg.sender] = true;
    }
    function executeProposal(uint256 proposalIndex) public {
        Proposal storage proposal = proposals[proposalIndex];
        require(!proposal.executed, "Proposal already executed");
        require(proposal.voteYes > minMembers, "Minimum members no voted
YES");
        proposal.executed = true;
    }
}

Output:

Q5: Write a Solidity function to implement a smart contract insurance policy, where users can be
compensated for losses that meet certain conditions.
Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
contract InsurancePolicy {
    struct Policies {
        bool isDead;
        bool accident;
    }   
    mapping(address => uint256) public policyholders;
    mapping(address => Policies) public policyholdersPolicies;
    uint256 private initialAmount;
    uint256 private payoutAmount;
    uint256 private policyExpiration;
    constructor(uint256 initialamount, uint256 payoutamount, uint256
expiryDateinDays) {
        initialAmount = initialamount;
        payoutAmount = payoutamount;
        policyExpiration = block.timestamp + (expiryDateinDays * 1 days);
    }
    function purchasePolicy(uint256 amount) public payable {
        require(amount >= initialAmount, "initialAmount is greater then amount
you paying");
        require(block.timestamp < policyExpiration, "Policy has expired");
        policyholders[msg.sender] = amount;
    }
    function updatePolicies(bool isdead, bool getaccident) public
    {
        policyholdersPolicies[msg.sender] = Policies(isdead, getaccident);
    }
    function fileClaim() public {
        require(policyholders[msg.sender] > 0, "No policy found for sender.");
        require(block.timestamp < policyExpiration, "Policy expired.");
        Policies storage policy = policyholdersPolicies[msg.sender];
        if (policy.isDead && policy.accident) {
            payable(msg.sender).transfer(payoutAmount);
        }
    }
}
Output:
Q6: Write a Solidity function to implement a token swap, where one ERC-20 token can be
exchanged for another.
Code:
// 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;
    }
    function swapTokens(uint256 amount) public {
        require(amount > 0, "Amount must be greater than 0");
        require(tokenA.balanceOf(msg.sender) >= amount, "Insufficient
balance");
        tokenA.approve(address(this), amount);
        tokenA.transferFrom(msg.sender, address(this), amount);
        uint256 swapRate = getSwapRate();
        uint256 receivedAmount = amount * swapRate;
        tokenB.transfer(msg.sender, receivedAmount);
    }
    function getSwapRate() public pure returns (uint256) {
        return 100;
    }
}
Q7: Write a Solidity function to implement a token vesting contract, where tokens are gradually
released over a period of time.
Code:
// SPDX-License-Identifier: MIT License
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;
    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");
        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);
        }
    }
}
Q8: Write a Solidity function to implement a gasless transfer, where tokens can be transferred
without requiring the user to pay for gas.
Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
import "./ERC20.sol";

contract GaslessTransfer {
    function transfer(
        address tokenAddress,
        address recipient,
        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");
    }
}
Output:
Q9: 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.
Code:
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.0;
contract USDT {
    uint256 private totalSupply;
    address private 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);
    }
}
Output:
Q10: Write a Solidity function to implement a prediction market for sports events, where users can
bet on the outcome of games and matches.
Code:
// SPDX-License-Identifier: MIT License

pragma solidity ^0.8.0;

import "hardhat/console.sol";

contract PredictionSportOutcomes {
   
    struct Sports {
        address creator;
        string gameEvent;
        uint256 betWin;
        uint256 betLose;
        uint256 completitionTime;
        bool outcome;
        bool timeHasGone;
        mapping(address => uint256) bidings;
        mapping(address => bool) bidOn;
    }
   
    mapping(uint256 => Sports) public sport;
    uint256 private totalsportgames = 0;
   
    function setSportEvent(string memory gameevent, uint256 completionTime)
public returns (uint256) {
        Sports storage _sport = sport[totalsportgames++];
        _sport.creator = msg.sender;
        _sport.gameEvent = gameevent;
        _sport.completitionTime = completionTime;
        return totalsportgames - 1;
    }
   
    function bidingOnSportOutcome(uint256 gameIndex, uint256 betAmount, bool
outcome) public payable {
        Sports storage _sport = sport[gameIndex];
        require(_sport.timeHasGone == false, "Time has passed for the game to
do biding.");
        require(betAmount * 1 ether > 0, "too little bet Amount");
        if (outcome == true) {
            _sport.betWin += betAmount;
            _sport.bidOn[msg.sender]=true;
        } else {
            _sport.betLose += betAmount;
            _sport.bidOn[msg.sender]=false;
        }
        _sport.bidings[msg.sender] += betAmount;
    }
   
    function setSportStatus(uint256 gameIndex, bool outcome) public {
        Sports storage _sport = sport[gameIndex];
        require(_sport.timeHasGone == false, "Time has passed for the game to
set status");
        require(_sport.creator == msg.sender, "Only creator can set status of
game");
        require(block.timestamp >= _sport.completitionTime, "Completition time
not reached");
        _sport.outcome = outcome;
        _sport.timeHasGone = true;
    }   
    function claimWinnings(uint256 gameIndex) public {
        Sports storage _sport = sport[gameIndex];
        require(_sport.timeHasGone == true, "Time hasn't passed for the game
status");
        require(_sport.bidings[msg.sender] > 0, "No winings owned");       
        uint256 totalbet = _sport.betWin + _sport.betLose;
        uint256 payout = address(this).balance * _sport.bidings[msg.sender] /
totalbet;       
        if (_sport.outcome == true && _sport.bidOn[msg.sender]==true) {
            payable(msg.sender).transfer(payout);
        }
        else if(_sport.outcome==false && _sport.bidOn[msg.sender]==false){
            payable(msg.sender).transfer(payout);
        }
        else{
            console.log("no winings, bad luck!");
        }
        _sport.bidings[msg.sender] = 0;
    }
}
Output:
Q11:
pragma: The pragma keyword is used to specify the version of Solidity the contract should be
compiled with. For example, pragma solidity ^0.8.0; specifies that the contract should be compiled
using Solidity version 0.8.0 or a later compatible version.

contract: A contract is the fundamental building block of a Solidity program. It represents a smart
contract that can be deployed on the blockchain and interacted with by other parties. For example:
contract MyContract {
// contract code here
}

state variable: A state variable is a variable declared at the contract level that maintains its value
across function calls. For example:
contract MyContract {
uint256 public myNumber; // state variable
}

function: A function is a block of code that performs a specific task. It can be called by other
contracts or external accounts to interact with the smart contract. For example:
contract MyContract {
function myFunction() public {
// function code here
}
}

modifier: A modifier is a way to modify the behavior of a function by adding additional checks or
conditions. For example:
contract MyContract {
address public owner;

modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}

function myFunction() public onlyOwner {


// function code here
}
}

event: An event is a way to log and track important state changes in a smart contract. It can be
emitted by a function to notify external parties of the change. For example:
contract MyContract {
event MyEvent(uint256 value);

function myFunction(uint256 value) public {


// function code here
emit MyEvent(value);
}
}

modifier keyword: The modifier keyword is used to define a new modifier that can be applied
to functions. For example:
contract MyContract {
modifier onlyOwner() {
// modifier code here
_;
}

function myFunction() public onlyOwner {


// function code here
}
}

emit keyword: The emit keyword is used to emit an event from within a function. For example:
contract MyContract {
event MyEvent(uint256 value);

function myFunction(uint256 value) public {


// function code here
emit MyEvent(value);
}
}
return: The return keyword is used to return a value from a function. For example:
contract MyContract {
function myFunction() public returns (uint256) {
// function code here
return 42;
}
}

require: The require keyword is used to add a condition that must be true for a function to execute.
If the condition is false, the function will revert and any changes made to the blockchain will be
reverted. For example:
contract MyContract {
function myFunction(uint256 value) public {
require(value > 0, "Value must be greater than 0");
// function code here
}
}

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;


}

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 {

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;

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

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;

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.

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;

}
}
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 {

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);

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);

}
addmod(uint x, uint y, uint k) returns (uint): compute (x + y) % k where the
addition 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 = 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 {

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

revert("Name cannot be empty");

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
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)
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...

}
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;

<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

// 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, (uin
t, uint[2], bytes))

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) {

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

// ...

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

You might also like