Skip to content

Instantly share code, notes, and snippets.

@bachdgvn
Created January 19, 2019 03:28
Show Gist options
  • Save bachdgvn/a713842a7f1a43986fd5d64289b97a5e to your computer and use it in GitHub Desktop.
Save bachdgvn/a713842a7f1a43986fd5d64289b97a5e to your computer and use it in GitHub Desktop.
pragma solidity ^0.5.0;
contract BCertz {
uint public certID;
address public owner;
uint public certCount;
struct Record {
address studentAddress;
string firstName;
string lastName;
string email;
string school;
string courseCode;
string status;
uint grade;
}
mapping(address => uint) public addressLookup;
mapping(uint => Record) public recordInfo;
constructor() public {
owner = msg.sender;
certID = 0;
}
function newRecord (address _studentAddress, string memory _fname, string memory _lname, string memory _email, string memory _school, string memory _courseCode, string memory _status, uint _grade) public {
require(msg.sender == owner, "You are not authorized to create a new record.");
recordInfo[certID].studentAddress = _studentAddress;
recordInfo[certID].firstName = _fname;
recordInfo[certID].lastName = _lname;
recordInfo[certID].email = _email;
recordInfo[certID].school = _school;
recordInfo[certID].courseCode = _courseCode;
recordInfo[certID].status = _status;
recordInfo[certID].grade = _grade;
addressLookup[_studentAddress] = certID;
certID += 1;
certCount += 1;
}
function updateRecord (uint _certID, address _studentAddress, string memory _fname, string memory _lname, string memory _email, string memory _school, string memory _courseCode, string memory _status, uint _grade) public {
require(msg.sender == owner, "You are not authorized to create a new record.");
recordInfo[_certID].studentAddress = _studentAddress;
recordInfo[_certID].firstName = _fname;
recordInfo[_certID].lastName = _lname;
recordInfo[_certID].email = _email;
recordInfo[_certID].school = _school;
recordInfo[_certID].courseCode = _courseCode;
recordInfo[_certID].status = _status;
recordInfo[_certID].grade = _grade;
}
function deleteRecord (uint _certID) public {
require(msg.sender == owner, "You are not authorized to delete this record.");
recordInfo[_certID].studentAddress = address(0x0);
recordInfo[_certID].firstName = "";
recordInfo[_certID].lastName = "";
recordInfo[_certID].email = "";
recordInfo[_certID].school = "";
recordInfo[_certID].courseCode = "";
recordInfo[_certID].status = "";
recordInfo[_certID].grade = 0;
certCount -= 1;
}
function studentChangeRecord (uint _certID, address _newAddress, string memory _newEmail) public {
require(msg.sender == recordInfo[_certID].studentAddress, "You are not authorized to edit this record.");
recordInfo[_certID].studentAddress = _newAddress;
recordInfo[_certID].email = _newEmail;
}
function GetRecordID (address _address) public view returns (uint) {
return addressLookup[_address];
}
function GetRecordAddress (uint _certID) public view returns(address) {
return recordInfo[_certID].studentAddress;
}
function GetFirstName (uint _certID) public view returns (string memory) {
return recordInfo[_certID].firstName;
}
function GetLastName (uint _certID) public view returns (string memory) {
return recordInfo[_certID].lastName;
}
function GetEmail (uint _certID) public view returns (string memory) {
return recordInfo[_certID].email;
}
function GetSchool (uint _certID) public view returns (string memory) {
return recordInfo[_certID].school;
}
function GetCourseCode (uint _certID) public view returns (string memory) {
return recordInfo[_certID].courseCode;
}
function GetStatus (uint _certID) public view returns (string memory) {
return recordInfo[_certID].status;
}
function GetGrade (uint _certID) public view returns (uint) {
return recordInfo[_certID].grade;
}
}
pragma solidity ^0.4.0;
/*
Temporary Hash Registrar
========================
This is a simplified version of a hash registrar. It is purporsefully limited:
names cannot be six letters or shorter, new auctions will stop after 4 years
and all ether still locked after 8 years will become unreachable.
The plan is to test the basic features and then move to a new contract in at most
2 years, when some sort of renewal mechanism will be enabled.
*/
contract AbstractENS {
function owner(bytes32 node) constant returns(address);
function resolver(bytes32 node) constant returns(address);
function ttl(bytes32 node) constant returns(uint64);
function setOwner(bytes32 node, address owner);
function setSubnodeOwner(bytes32 node, bytes32 label, address owner);
function setResolver(bytes32 node, address resolver);
function setTTL(bytes32 node, uint64 ttl);
event Transfer(bytes32 indexed node, address owner);
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
event NewResolver(bytes32 indexed node, address resolver);
event NewTTL(bytes32 indexed node, uint64 ttl);
}
/**
* @title Deed to hold ether in exchange for ownership of a node
* @dev The deed can be controlled only by the registrar and can only send ether back to the owner.
*/
contract Deed {
address public registrar;
address constant burn = 0xdead;
uint public creationDate;
address public owner;
event OwnerChanged(address newOwner);
event DeedClosed();
bool active;
modifier onlyRegistrar {
if (msg.sender != registrar) throw;
_;
}
modifier onlyActive {
if (!active) throw;
_;
}
function Deed() {
registrar = msg.sender;
creationDate = now;
active = true;
}
function setOwner(address newOwner) onlyRegistrar {
owner = newOwner;
OwnerChanged(newOwner);
}
function setRegistrar(address newRegistrar) onlyRegistrar {
registrar = newRegistrar;
}
function setBalance(uint newValue) onlyRegistrar onlyActive payable {
// Check if it has enough balance to set the value
if (this.balance < newValue) throw;
// Send the difference to the owner
if (!owner.send(this.balance - newValue)) throw;
}
/**
* @dev Close a deed and refund a specified fraction of the bid value
* @param refundRatio The amount*1/1000 to refund
*/
function closeDeed(uint refundRatio) onlyRegistrar onlyActive {
active = false;
if (! burn.send(((1000 - refundRatio) * this.balance)/1000)) throw;
DeedClosed();
destroyDeed();
}
/**
* @dev Close a deed and refund a specified fraction of the bid value
*/
function destroyDeed() {
if (active) throw;
if(owner.send(this.balance))
selfdestruct(burn);
else throw;
}
// The default function just receives an amount
function () payable {}
}
/**
* @title HANA
* @dev The HANA handles the auction process for each subnode of the node it owns.
*/
contract HANA {
AbstractENS public ens;
bytes32 public rootNode;
mapping (bytes32 => entry) public entries;
mapping (bytes32 => Deed) public sealedBids;
enum Mode { Open, Auction, Owned, Forbidden }
uint32 constant auctionLength = 7 days;
uint32 constant revealPeriod = 24 hours;
uint32 constant initialAuctionPeriod = 2 weeks;
uint constant minPrice = 0.01 ether;
uint public registryCreated;
event AuctionStarted(bytes32 indexed hash, uint auctionExpiryDate);
event NewBid(bytes32 indexed hash, uint deposit);
event BidRevealed(bytes32 indexed hash, address indexed owner, uint value, uint8 status);
event HashRegistered(bytes32 indexed hash, address indexed owner, uint value, uint now);
event HashReleased(bytes32 indexed hash, uint value);
event HashInvalidated(bytes32 indexed hash, string indexed name, uint value, uint now);
struct entry {
Mode status;
Deed deed;
uint registrationDate;
uint value;
uint highestBid;
}
modifier onlyOwner(bytes32 _hash) {
entry h = entries[_hash];
if (msg.sender != h.deed.owner() || h.status != Mode.Owned) throw;
_;
}
/**
* @dev Constructs a new Registrar, with the provided address as the owner of the root node.
* @param _ens The address of the ENS
* @param _rootNode The hash of the rootnode.
*/
function Registrar(address _ens, bytes32 _rootNode) {
ens = AbstractENS(_ens);
rootNode = _rootNode;
registryCreated = now;
}
/**
* @dev Returns the maximum of two unsigned integers
* @param a A number to compare
* @param b A number to compare
* @return The maximum of two unsigned integers
*/
function max(uint a, uint b) internal constant returns (uint max) {
if (a > b)
return a;
else
return b;
}
/**
* @dev Returns the minimum of two unsigned integers
* @param a A number to compare
* @param b A number to compare
* @return The minimum of two unsigned integers
*/
function min(uint a, uint b) internal constant returns (uint min) {
if (a < b)
return a;
else
return b;
}
/**
* @dev Returns the length of a given string
* @param s The string to measure the length of
* @return The length of the input string
*/
function strlen(string s) internal constant returns (uint) {
// Starting here means the LSB will be the byte we care about
uint ptr;
uint end;
assembly {
ptr := add(s, 1)
end := add(mload(s), ptr)
}
for (uint len = 0; ptr < end; len++) {
uint8 b;
assembly { b := and(mload(ptr), 0xFF) }
if (b < 0x80) {
ptr += 1;
} else if(b < 0xE0) {
ptr += 2;
} else if(b < 0xF0) {
ptr += 3;
} else if(b < 0xF8) {
ptr += 4;
} else if(b < 0xFC) {
ptr += 5;
} else {
ptr += 6;
}
}
return len;
}
/**
* @dev Start an auction for an available hash
*
* Anyone can start an auction by sending an array of hashes that they want to bid for.
* Arrays are sent so that someone can open up an auction for X dummy hashes when they
* are only really interested in bidding for one. This will increase the cost for an
* attacker to simply bid blindly on all new auctions. Dummy auctions that are
* open but not bid on are closed after a week.
*
* @param _hash The hash to start an auction on
*/
function startAuction(bytes32 _hash) {
entry newAuction = entries[_hash];
// Ensure the hash is available, and no auction is currently underway
if ((newAuction.status == Mode.Auction && now < newAuction.registrationDate)
|| newAuction.status == Mode.Owned
|| newAuction.status == Mode.Forbidden
|| now > registryCreated + 4 years)
throw;
// for the first month of the registry, make longer auctions
newAuction.registrationDate = max(now + auctionLength, registryCreated + initialAuctionPeriod);
newAuction.status = Mode.Auction;
newAuction.value = 0;
newAuction.highestBid = 0;
AuctionStarted(_hash, newAuction.registrationDate);
}
/**
* @dev Start multiple auctions for better anonymity
* @param _hashes An array of hashes, at least one of which you presumably want to bid on
*/
function startAuctions(bytes32[] _hashes) {
for (uint i = 0; i < _hashes.length; i ++ ) {
startAuction(_hashes[i]);
}
}
/**
* @dev Hash the values required for a secret bid
* @param hash The node corresponding to the desired namehash
* @param owner The address which will own the
* @param value The bid amount
* @param salt A random value to ensure secrecy of the bid
* @return The hash of the bid values
*/
function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) constant returns (bytes32 sealedBid) {
return sha3(hash, owner, value, salt);
}
/**
* @dev Submit a new sealed bid on a desired hash in a blind auction
*
* Bids are sent by sending a message to the main contract with a hash and an amount. The hash
* contains information about the bid, including the bidded hash, the bid amount, and a random
* salt. Bids are not tied to any one auction until they are revealed. The value of the bid
* itself can be masqueraded by sending more than the value of your actual bid. This is
* followed by a 24h reveal period. Bids revealed after this period will be burned and the ether unrecoverable.
* Since this is an auction, it is expected that most public hashes, like known domains and common dictionary
* words, will have multiple bidders pushing the price up.
*
* @param sealedBid A sealedBid, created by the shaBid function
*/
function newBid(bytes32 sealedBid) payable {
if (address(sealedBids[sealedBid]) > 0 ) throw;
// creates a new hash contract with the owner
Deed newBid = new Deed();
sealedBids[sealedBid] = newBid;
NewBid(sealedBid, msg.value);
if (!newBid.send(msg.value)) throw;
}
/**
* @dev Submit the properties of a bid to reveal them
* @param _hash The node in the sealedBid
* @param _owner The address in the sealedBid
* @param _value The bid amount in the sealedBid
* @param _salt The sale in the sealedBid
*/
function unsealBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt) {
bytes32 seal = shaBid(_hash, _owner, _value, _salt);
Deed bid = sealedBids[seal];
if (address(bid) == 0 ) throw;
sealedBids[seal] = Deed(0);
bid.setOwner(_owner);
entry h = entries[_hash];
/*
A penalty is applied for submitting unrevealed bids, which could otherwise
be used as a threat of revealing a bid higher than the second-highest
bid, to extort the winner into paying them.
*/
if (bid.creationDate() > h.registrationDate - revealPeriod
|| now > h.registrationDate
|| _value < minPrice) {
// bid is invalid, burn 99%
bid.closeDeed(10);
BidRevealed(_hash, _owner, _value, 0);
} else if (_value > h.highestBid) {
// new winner
// cancel the other bid, refund 99.9%
if(address(h.deed) != 0) {
Deed previousWinner = h.deed;
previousWinner.closeDeed(999);
}
// set new winner
// per the rules of a vickery auction, the value becomes the previous highestBid
h.value = h.highestBid;
h.highestBid = _value;
h.deed = bid;
bid.setBalance(_value);
BidRevealed(_hash, _owner, _value, 2);
} else if (_value > h.value) {
// not winner, but affects second place
h.value = _value;
bid.closeDeed(999);
BidRevealed(_hash, _owner, _value, 3);
} else {
// bid doesn't affect auction
bid.closeDeed(999);
BidRevealed(_hash, _owner, _value, 4);
}
}
/**
* @dev Cancel a bid
* @param seal The value returned by the shaBid function
*/
function cancelBid(bytes32 seal) {
Deed bid = sealedBids[seal];
// If the bid hasn't been revealed long after any possible auction date, then close it
if (address(bid) == 0
|| now < bid.creationDate() + auctionLength * 12
|| bid.owner() > 0) throw;
// There is a fee for cancelling an old bid, but it's smaller than revealing it
bid.setOwner(msg.sender);
bid.closeDeed(5);
sealedBids[seal] = Deed(0);
BidRevealed(seal, 0, 0, 5);
}
/**
* @dev Finalize an auction after the registration date has passed
* @param _hash The hash of the name the auction is for
*/
function finalizeAuction(bytes32 _hash) {
entry h = entries[_hash];
if (now < h.registrationDate
|| h.highestBid == 0
|| h.status != Mode.Auction) throw;
// set the hash
h.status = Mode.Owned;
h.value = max(h.value, minPrice);
// Assign the owner in ENS
ens.setSubnodeOwner(rootNode, _hash, h.deed.owner());
Deed deedContract = h.deed;
deedContract.setBalance(h.value);
HashRegistered(_hash, deedContract.owner(), h.value, now);
}
/**
* @dev The owner of a domain may transfer it to someone else at any time.
* @param _hash The node to transfer
* @param newOwner The address to transfer ownership to
*/
function transfer(bytes32 _hash, address newOwner) onlyOwner(_hash) {
entry h = entries[_hash];
h.deed.setOwner(newOwner);
ens.setSubnodeOwner(rootNode, _hash, newOwner);
}
/**
* @dev After some time, the owner can release the property and get their ether back
* @param _hash The node to release
*/
function releaseDeed(bytes32 _hash) onlyOwner(_hash) {
entry h = entries[_hash];
Deed deedContract = h.deed;
if (now < h.registrationDate + 1 years
|| now > registryCreated + 8 years) throw;
h.status = Mode.Open;
ens.setSubnodeOwner(rootNode, _hash, 0);
deedContract.closeDeed(1000);
HashReleased(_hash, h.value);
}
/**
* @dev Submit a name 6 characters long or less. If it has been registered,
* the submitter will earn 10% of the deed value. We are purposefully
* handicapping the simplified registrar as a way to force it into being restructured
* in a few years.
* @param unhashedName An invalid name to search for in the registry.
*
*/
function invalidateName(string unhashedName) {
if (strlen(unhashedName) > 6 ) throw;
bytes32 hash = sha3(unhashedName);
entry h = entries[hash];
h.status = Mode.Forbidden;
ens.setSubnodeOwner(rootNode, hash, 0);
if(address(h.deed) != 0) {
// Reward the discoverer with 10% of the deed
// The previous owner gets nothing
h.deed.setOwner(msg.sender);
h.deed.closeDeed(100);
}
HashInvalidated(hash, unhashedName, h.value, now);
}
/**
* @dev Transfers the deed to the current registrar, if different from this one.
* Used during the upgrade process to a permanent registrar.
* @param _hash The name hash to transfer.
*/
function transferRegistrars(bytes32 _hash) onlyOwner(_hash) {
var registrar = ens.owner(rootNode);
if(registrar == address(this))
throw;
entry h = entries[_hash];
h.deed.setRegistrar(registrar);
h.status = Mode.Forbidden;
}
}
pragma solidity ^0.4.11;
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
uint256 public totalSupply;
function balanceOf(address who) public constant returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) onlyOwner public {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public constant returns (uint256 balance) {
return balances[_owner];
}
}
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public constant returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* @dev https://github.com/ethereum/EIPs/issues/20
* @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
uint256 _allowance = allowed[_from][msg.sender];
// Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
// require (_value <= _allowance);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = _allowance.sub(_value);
Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
/**
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
*/
function increaseApproval (address _spender, uint _addedValue)
returns (bool success) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval (address _spender, uint _subtractedValue)
returns (bool success) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
/**
* @title Mintable token
* @dev Simple ERC20 Token example, with mintable token creation
* @dev Issue: * https://github.com/OpenZeppelin/zeppelin-solidity/issues/120
* Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
*/
contract MintableToken is StandardToken, Ownable {
event Mint(address indexed to, uint256 amount);
event MintFinished();
bool public mintingFinished = false;
modifier canMint() {
require(!mintingFinished);
_;
}
/**
* @dev Function to mint tokens
* @param _to The address that will receive the minted tokens.
* @param _amount The amount of tokens to mint.
* @return A boolean that indicates if the operation was successful.
*/
function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
Mint(_to, _amount);
Transfer(0x0, _to, _amount);
return true;
}
/**
* @dev Function to stop minting new tokens.
* @return True if the operation was successful.
*/
function finishMinting() onlyOwner public returns (bool) {
mintingFinished = true;
MintFinished();
return true;
}
}
contract MYMY is MintableToken {
string public name = 'MYMY';
string public symbol = 'MYM';
uint public decimals = 18;
uint public INITIAL_SUPPLY = 12000;
function MYMY() {
totalSupply = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
}
}
pragma solidity ^0.4.25;
library SafeMath {
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b)
internal
pure
returns (uint256 c)
{
if (a == 0) {
return 0;
}
c = a * b;
require(c / a == b, "SafeMath mul failed");
return c;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
require(b <= a, "SafeMath sub failed");
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b)
internal
pure
returns (uint256 c)
{
c = a + b;
require(c >= a, "SafeMath add failed");
return c;
}
/**
* @dev gives square root of given x.
*/
function sqrt(uint256 x)
internal
pure
returns (uint256 y)
{
uint256 z = ((add(x,1)) / 2);
y = x;
while (z < y)
{
y = z;
z = ((add((x / z),z)) / 2);
}
}
/**
* @dev gives square. batchplies x by x
*/
function sq(uint256 x)
internal
pure
returns (uint256)
{
return (mul(x,x));
}
/**
* @dev x to the power of y
*/
function pwr(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
if (x==0)
return (0);
else if (y==0)
return (1);
else
{
uint256 z = x;
for (uint256 i=1; i < y; i++)
z = mul(z,x);
return (z);
}
}
}
contract TOMO{
address public admin;
address[] public players;
uint8[] public luckynumbers;
uint256 sizebet;
uint256 win;
uint256 _seed = now;
event BetResult(
address from,
uint256 betvalue,
uint256 prediction,
uint8 luckynumber,
bool win,
uint256 wonamount
);
event LuckyDrop(
address from,
uint256 betvalue,
uint256 prediction,
uint8 luckynumber,
string congratulation
);
event Shake(
address from,
bytes32 make_chaos
);
constructor() public{
admin = 0x1E1C1Fa8Ee39151ba082daE2F24E906882F4681C;
}
function random() private view returns (uint8) {
return uint8(uint256(keccak256(block.timestamp, block.difficulty, _seed))%100); // random 0-99
}
function bet(uint8 under) public payable{
require(msg.value >= .001 ether);
require(under > 0 && under < 96);
sizebet = msg.value;
win = uint256 (sizebet*98/under);
uint8 _random = random();
luckynumbers.push(_random);
if (_random < under) {
if (msg.value*98/under < address(this).balance) {
msg.sender.transfer(win);
emit BetResult(msg.sender, msg.value, under, _random, true, win);
}
else {
msg.sender.transfer(address(this).balance);
emit BetResult(msg.sender, msg.value, under, _random, true, address(this).balance);
}
} else {
emit BetResult(msg.sender, msg.value, under, _random, false, 0x0);
}
}
modifier onlyAdmin() {
// Ensure the participant awarding the ether is the admin
require(msg.sender == admin);
_;
}
function withdrawEth(address to, uint256 balance) onlyAdmin {
if (balance == uint256(0x0)) {
to.transfer(address(this).balance);
} else {
to.transfer(balance);
}
}
function getLuckynumber() public view returns(uint8[]) {
// Return list of luckynumbers
return luckynumbers;
}
function shake(uint256 choose_a_number_to_chaos_the_algo) public {
_seed = uint256(keccak256(choose_a_number_to_chaos_the_algo));
emit Shake(msg.sender, "You changed the algo");
}
}
//https://shawntabrizi.com/crypto/verify-ethereum-contracts-using-web3-js-and-solc/
var fs = require('fs')
var solc = require('solc')
var Web3 = require('web3')
var web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/xxxxxxxxx"))
var contractTests = {
BCertz: {
solc_version: "v0.5.0+commit.1d4f565a",
contract_name: "BCertz",
contract_filename: "BCertz.sol",
contract_address: "0x185a4c9bc3013204c4e99d4fe613c0959f5fb776",
is_optimized: true,
},
TOMO: {
solc_version: "v0.4.25+commit.59dbf8f1",
contract_name: "TOMO",
contract_filename: "TOMO.sol",
contract_address: "0xbd87755ea2bdc1ac8ef8610af06cbe842af78a0d",
is_optimized: true,
},
MYMY: {
solc_version: "v0.4.11+commit.68ef5810",
contract_name: "MYMY",
contract_filename: "MYMY.sol",
contract_address: "0x90933f6602fdc3d724cbadd949fb38862c54db94",
is_optimized: true,
},
HANA: {
solc_version: "v0.4.4+commit.4633f3de",
contract_name: "HANA",
contract_filename: "HANA.sol",
contract_address: "0x299ecad926bbb6d8ab16e98bd23da52d0e2f82ba",
is_optimized: true,
}
}
// Set up contract to compile
var selectedContractName = 'HANA';
var selectedContract = contractTests[selectedContractName]
var solc_version = selectedContract.solc_version
var contract_name = selectedContract.contract_name
var contract_filename = selectedContract.contract_filename
var contract_address = selectedContract.contract_address
var is_optimized = selectedContract.is_optimized
var contractSource = {
content: fs.readFileSync('./' + contract_filename, 'utf8')
}
let input = {
language: 'Solidity',
sources: {},
settings: {
optimizer: is_optimized ? {
enabled: true
} : {
enabled: false
},
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
}
// Set up contract source code
input.sources[contract_filename] = contractSource;
// Start to compile
solc.loadRemoteVersion(solc_version, async function (err, solc_specific) {
console.log('solc_specific: ', solc_specific.version());
if (!err) {
// `output` here contains the JSON output as specified in the documentation
var output = JSON.parse(solc_specific.compile(JSON.stringify(input)))
let { solc_minor, solc_patch } = getSematicVersioning(solc_version)
var creation_bytecode = "0x";
var deployed_bytecode = "0x";
let brigde = '';
if (solc_minor >= 4 && solc_patch >= 7) {
brigde = contract_filename;
}
creation_bytecode += output.contracts[brigde][contract_name].evm.bytecode.object;
console.log('creation_bytecode: ', creation_bytecode);
deployed_bytecode += output.contracts[brigde][contract_name].evm.deployedBytecode.object;
console.log('deployed_bytecode: ', deployed_bytecode);
var blockchain_bytecode = await web3.eth.getCode(contract_address);
processed_deployed_bytecode = removeSwarmHashOfMetadataFile(deployed_bytecode);
processed_blockchain_bytecode = removeSwarmHashOfMetadataFile(blockchain_bytecode);
if (processed_blockchain_bytecode == processed_deployed_bytecode) {
console.log("Verified!")
} else {
console.log("Not Verified")
}
} else {
console.log('error: ', err);
}
});
function getSematicVersioning(solc_version) {
// Semantic versioning
let solc_minor = parseInt(solc_version.match(/v\d+?\.\d+?\.\d+?[+-]/gi)[0].match(/\.\d+/g)[0].slice(1))
let solc_patch = parseInt(solc_version.match(/v\d+?\.\d+?\.\d+?[+-]/gi)[0].match(/\.\d+/g)[1].slice(1))
return {
solc_minor,
solc_patch
}
}
function removeSwarmHashOfMetadataFile(bytecode) {
// Semantic versioning
let { solc_minor, solc_patch } = getSematicVersioning(solc_version)
if (solc_minor >= 4 && solc_patch >= 22) {
var starting_point = bytecode.lastIndexOf('6080604052');
var ending_point = bytecode.search('a165627a7a72305820');
return bytecode.slice(starting_point, ending_point);
} else if (solc_minor >= 4 && solc_patch >= 7) {
var starting_point = bytecode.lastIndexOf('6060604052');
var ending_point = bytecode.search('a165627a7a72305820');
return bytecode.slice(starting_point, ending_point);
} else {
return bytecode;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment