Professional Documents
Culture Documents
19F0256 8A Assignment2&3
19F0256 8A Assignment2&3
1. Write a Solidity function to implement a decentralized identity system, where users can prove
their identity without relying on a centralized authority.
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.
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
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
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
struct Proposal {
uint256 id;
string description;
uint256 voteYes;
uint256 voteNo;
bool executed;
}
constructor(uint256 _quorum) {
quorum = _quorum; // Minimum number of people for voting
}
function addMember(address _member) public onlyOwner {
members[_member] = false;
}
5. Write a Solidity function to implement a smart contract insurance policy, where users can be
compensated for losses that meet certain conditions.
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
6. Write a Solidity function to implement a token swap, where one ERC-20 token can be exchanged
for another.
contract TokenSwap {
UserToken public tokenA;
UserToken public tokenB;
7. Write a Solidity function to implement a token vesting contract, where tokens are gradually
released over a period of time.
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
contract TokenVesting {
using SafeMath for uint256;
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;
}
released[msg.sender] = released[msg.sender].add(unreleased);
token.transfer(msg.sender, unreleased);
revoked[msg.sender] = true;
released[msg.sender] = 0;
if (refund > 0) {
token.transfer(msg.sender, refund);
}
emit Revoked(msg.sender);
}
8. Write a Solidity function to implement a gasless transfer, where tokens can be transferred
without requiring the user to pay for gas.
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.
contract USDT {
string public name = "USD Tether";
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.
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
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.
return x + y;
}
return balances[account];
}
payable for functions: Allows them to receive Ether together with a call.
balances[msg.sender] += amount;
}
constant for state variables: Disallows assignment (except initialisation), does not occupy
storage slot.
contract MyContract {
immutable for state variables: Allows exactly one assignment at construction time and is
constant afterwards. Is stored in code.
contract MyContract {
constructor() {
OWNER = msg.sender;
}
}
virtual for functions and modifiers: Allows the function’s or modifier’s behaviour to be
changed in derived contracts.
contract Base {
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
contract VisibilityExample {
myNumber = _number;
return myNumber;
}
}
private : only visible in the current contract
contract VisibilityExample {
myNumber = _number;
return myNumber;
}
}
external : only visible externally (only for functions) - i.e. can only be message-called
(via this.func )
contract VisibilityExample {
}
}
internal : only visible internally
contract VisibilityExample {
myNumber = _number;
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3
return myNumber;
setNumber(42);
}
}
Type Information
type(C).name ( string ): the name of the contract
contract MyContract {
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 {
return type(MyContract).creationCode;
}
}
type(C).runtimeCode ( bytes memory ): runtime bytecode of the given contract, see Type
Information.
contract MyContract {
return type(MyContract).runtimeCode;
}
}
type(I).interfaceId ( bytes4 ): value containing the EIP-165 interface identifier of the
given interface, see Type Information.
interface MyInterface {
return type(MyInterface).interfaceId;
}
}
type(T).min ( T ): the minimum value representable by the integer type T , see Type
Information.
contract MyContract {
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 {
return type(uint8).max;
}
}
Contract-related
this (current contract’s type): the current contract, explicitly convertible
to address or address payable
contract MyContract {
}
}
super : a contract one level higher in the inheritance hierarchy
contract A {
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3
uint256 public x;
constructor(uint256 _x) {
x = _x;
contract B is A {
}
}
selfdestruct(address payable recipient) : destroy the current contract, sending its funds to
the given address
contract MyContract {
constructor() {
owner = payable(msg.sender);
}
19F0256 | Eqan Ahmad | BSCS | 8A | Blockchain Ass#2&3
selfdestruct(owner); // destroys the contract and sends its funds to the owner
address
}
}
function recoverAddress(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
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
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
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.
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
if (bytes(name).length == 0) {
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
(see EIP-4399 )
block.timestamp ( uint ): current block timestamp in seconds since Unix epoch
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
// function code...
}
Members of address
if (!sent) {
// handle failure
}
<address payable>.transfer(uint256 amount) : send given amount of Wei to Address, throws
on failure
// bytes.concat() example
// string.concat() example
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, (...))
// ...
}
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);