Created
January 19, 2019 03:28
-
-
Save bachdgvn/a713842a7f1a43986fd5d64289b97a5e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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