19f0217 8B Assignment2&3
19f0217 8B Assignment2&3
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]);
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
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");
_;
}
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);
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
_;
}
emit keyword: The emit keyword is used to emit an event from within a function. For example:
contract MyContract {
event MyEvent(uint256 value);
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.
return x + y;
}
return balances[account];
}
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;
}
}
contract Base {
}
contract Derived is 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 {
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
contract VisibilityExample {
}
}
internal only visible internally
contract VisibilityExample {
myNumber = _number;
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.
contract MyContract {
}
}
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;
}
}
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
contract MyContract {
}
}
super: a contract one level higher in the inheritance hierarchy
contract A {
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);
selfdestruct(owner); // destroys the contract and sends its funds to the owner address
}
}
function recoverAddress(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 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
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) {
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
}
tx.origin (address): sender of the transaction (full call chain)
// function code...
}
Members of address
address myAddress = 0x1234567890123456789012345678901234567890;
<address>.balance (uint256): balance of the Address in Wei
if (!sent) {
// handle failure
}
<address payable>.transfer(uint256 amount): send given amount of Wei
to Address, throws on failure
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
// string.concat() example
// ...
}
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);