Created
December 5, 2019 13:04
-
-
Save gatherheart/3ebabb391824614f056cef03dd0f4419 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 pop(uint256 [] storage array, uint256 idx) internal returns(uint256){ | |
uint256 ret = array[idx]; | |
array.removeItem(idx); | |
return ret; | |
} | |
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 Database { | |
constructor () public {} | |
} |
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"; | |
contract ERC20 is IERC20{ | |
string public name = "Used2BlockCoin"; | |
string public symbol = "UBC"; | |
uint8 public decimals = 0; | |
mapping (address => uint256) private balances; | |
mapping (address => mapping (address => uint256)) private allowed; | |
uint256 private _totalSupply; | |
// Address Should not be Zero | |
modifier NotZeroAddr(address addr){ | |
require(addr != address(0)); | |
_; | |
} | |
constructor () public{ | |
_totalSupply = 10**18; | |
balances[tx.origin] = _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[tx.origin] >= value | |
&& balances[to] + value > balances[to] | |
); | |
_transfer(tx.origin, to, value); | |
return true; | |
} | |
function _transfer(address _from, address to, uint256 value) private{ | |
require(balances[_from] - value < balances[_from] && balances[to] + value > balances[to]); | |
balances[_from] -= value; | |
balances[to] += value; | |
emit Transfer(_from, to, value); | |
} | |
function approve(address spender, uint256 value) external NotZeroAddr(spender) returns (bool) { | |
allowed[tx.origin][spender] = value; | |
emit Approval(tx.origin, 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][tx.origin] >= value); | |
_transfer(_from, to, value); | |
allowed[_from][tx.origin] -= 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; | |
interface IERC20 { | |
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.4.22 < 0.6.0; | |
contract Ownerable { | |
// event | |
event OwnerLog(address); | |
address public owner; | |
constructor() public{ | |
owner = msg.sender; | |
emit OwnerLog(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.22 <0.6.0; | |
pragma experimental ABIEncoderV2; | |
contract Test { | |
Test2 [] public t2; | |
address buyer; | |
function tmp() view public returns(uint256){ | |
return now; | |
} | |
function tmp2() public { | |
t2.push(new Test2()); | |
} | |
function tmp3() public view returns(address){ | |
return address(t2[0]); | |
} | |
function tmp4() public view returns(bool){ | |
return t2[0].tmp(); | |
} | |
function tmp5() public { | |
buyer = msg.sender; | |
} | |
function tmp6() public view returns(address){ | |
return buyer; | |
} | |
function tmp7() public view returns(string [] memory){ | |
return ("HelloWorld", "Test", "Works"); | |
} | |
} | |
contract Test2 { | |
function tmp() pure public returns(bool){ | |
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 "./ERC20.sol"; | |
import "./StringUtils.sol"; | |
contract Transaction { | |
using StringUtils for string; | |
ERC20 Bank; | |
address public seller; // owner contract id | |
address buyer; | |
address public validator; | |
string orderId; // order object id | |
address txid; // transaction id | |
uint256 txTime; // the time of transaction date | |
uint8 txStatus; // 0 waiting / 1 Reported / 2 Invalid Transaction / 3 Valid Transaction | |
uint256 public fee; | |
uint256 public PoS; | |
// seller's information | |
string sellerEmail; | |
string sellerPhone; | |
uint256 public productId; | |
uint256 public amount; // the price of product | |
string message; | |
Validation public report; // the list of reports about seller's history | |
struct Validation { | |
uint256 timeStamp; // report time | |
string nameOfPage; // reference page | |
string nameofSite; | |
uint256 accessTime; | |
string url; // reference url | |
} | |
constructor (string memory orderId_, address buyer_, address seller_, string memory sellerEmail_, string memory sellerPhone_, | |
uint256 amount_, string memory message_, address bank_, uint256 fee_, uint256 PoS_) public { | |
Bank = ERC20(bank_); | |
orderId = orderId_; | |
buyer = buyer_; | |
seller = seller_; | |
sellerEmail = sellerEmail_; | |
sellerPhone = sellerPhone_; | |
txTime = now; | |
message = message_; | |
amount = amount_; | |
PoS = PoS_; | |
fee = fee_; | |
} | |
// Paramerters | |
// uint256 timeStamp; // report time | |
// string nameOfPage; // reference page | |
// string nameofSite; | |
// uint256 accessTime; // Unix time Stamp | |
// string url; // reference url | |
function validate(string memory nameOfPage, string memory nameofSite, uint256 accessTime, string memory url) public { | |
// PoS applied here | |
require(PoS >= amount && Bank.balanceOf(tx.origin) >= amount + PoS); | |
Validation memory v; | |
v.timeStamp = now; | |
v.nameOfPage = nameOfPage; | |
v.nameofSite = nameofSite; | |
v.accessTime = accessTime; | |
v.url = url; | |
report = v; | |
validator = tx.origin; | |
} | |
function getInfo() public view returns (address, string memory){ | |
string memory ret; | |
string memory delim = "#"; | |
string memory tmp = | |
string(abi.encodePacked(uint2str(txTime), delim, sellerEmail, delim, sellerPhone, '\n\n')); | |
ret = string(abi.encodePacked(ret, tmp)); | |
return (seller, ret); | |
} | |
function getOrderId() public view returns(string memory){ | |
return orderId; | |
} | |
function getBuyer() public view returns (address){ | |
return buyer; | |
} | |
function getSeller() public view returns (address){ | |
return seller; | |
} | |
function getSellerEmail() public view returns(string memory){ | |
return sellerEmail; | |
} | |
function getSellerPhone() public view returns(string memory){ | |
return sellerPhone; | |
} | |
function getValidator() public view returns (address){ | |
return validator; | |
} | |
function getAmount() public view returns (uint256){ | |
return amount; | |
} | |
function getFee() public view returns (uint256){ | |
return fee; | |
} | |
function setStatus(uint8 status) public { | |
require(tx.origin == buyer); | |
txStatus = status; | |
} | |
function getStatus() public view returns(uint8){ | |
return txStatus; | |
} | |
function getValidation() public view returns (string memory){ | |
string memory delim = "#"; | |
Validation memory v = report; | |
string memory ret = string(abi.encodePacked(uint2str(v.timeStamp), delim, v.nameOfPage, delim, | |
v.nameofSite, delim, uint2str(v.accessTime), delim, v.url, '\n\n')); | |
return ret; | |
} | |
/*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 "./ERC20.sol"; | |
import "./Ownerable.sol"; | |
import "./ArrayUtils.sol"; | |
import "./StringUtils.sol"; | |
import "./Transaction.sol"; | |
contract Used2Block is Ownerable { | |
using ArrayUtils for uint256 []; | |
using ArrayUtils for address []; | |
using StringUtils for string; | |
mapping (string => address []) fraudHistoryPhone; | |
mapping (address => address []) fraudHistoryAddress; | |
mapping (string => address []) fraudHistoryEmail; | |
mapping(string => address) transactions; | |
// transaction Pool | |
address [] public openTxids; | |
// Bank Smart Contract | |
ERC20 Bank; | |
constructor (address bank) public { | |
Bank = ERC20(bank); | |
} | |
function getTxLen() public view returns (uint256){ | |
return openTxids.length; | |
} | |
function getBalance(address id) public view returns(uint256){ | |
return Bank.balanceOf(id); | |
} | |
// return types | |
// address Transcation address | |
// uint8 status | |
// address Seller address | |
// String Seller's information | |
function getOpenTx(uint256 idx) public view returns(address, uint8, address, string memory){ | |
require(idx < openTxids.length); | |
address seller; | |
string memory tmp; | |
Transaction t = Transaction(openTxids[idx]); | |
(seller, tmp) = t.getInfo(); | |
return (openTxids[idx], t.getStatus(), seller, tmp); | |
} | |
// return types | |
// (string => uint256 []) fraudHistoryPhone; | |
// (address => uint256 []) fraudHistoryAddress; | |
// (string => uint256 []) fraudHistoryEmail; | |
function findFraudWithPhone(string memory phone) public view returns (address [] memory){ | |
return fraudHistoryPhone[phone]; | |
} | |
function findFraudWithAddres(address seller) public view returns (address [] memory){ | |
return fraudHistoryAddress[seller]; | |
} | |
function findFraudWithEmail(string memory email) public view returns (address [] memory){ | |
return fraudHistoryEmail[email]; | |
} | |
function getValidation(address txid) public view returns (string memory){ | |
return Transaction(txid).getValidation(); | |
} | |
// 0 == waiting | 1 == Validated | 2 == terminated | 3 == completed | |
function getStatus(address txid) public view returns (uint8){ | |
return Transaction(txid).getStatus(); | |
} | |
function getTxAddress(string memory orderId) public view returns (address){ | |
return transactions[orderId]; | |
} | |
function getOrderId(address txid) public view returns (string memory){ | |
return Transaction(txid).getOrderId(); | |
} | |
function makeTx(string memory orderId, address seller, string memory sellerEmail, string memory sellerPhone, | |
uint256 amount, string memory message, uint256 fee, uint256 PoS) public { | |
// seller should not be same with buyer | |
require(msg.sender != seller); | |
// amount_ * 1.05 = amount + fee | |
require(fee >= 0 && amount > 0 && Bank.balanceOf(msg.sender) >= (amount + fee)); | |
Transaction tx_ = new Transaction(orderId, msg.sender, seller, sellerEmail, sellerPhone, amount, message, address(Bank), fee, PoS); | |
openTxids.push(address(tx_)); | |
transactions[orderId] = address(tx_); | |
} | |
function validate(address txid, string memory nameOfPage, string memory nameofSite, uint256 accessTime, string memory url) public { | |
address seller = Transaction(txid).getSeller(); | |
// sender should not be validator and transaction is not validated | |
require(seller != msg.sender && Transaction(txid).getStatus() < 1); | |
Transaction(txid).validate(nameOfPage, nameofSite, accessTime, url); | |
Transaction(txid).setStatus(1); | |
} | |
// Complete transaction | |
function completeTx(address txid) public{ | |
address buyer = Transaction(txid).getBuyer(); | |
address seller = Transaction(txid).getSeller(); | |
address validator = Transaction(txid).getValidator(); | |
uint256 amount = Transaction(txid).getAmount(); | |
uint256 fee = Transaction(txid).getFee(); | |
// msg sender should be buyer | |
require(buyer == msg.sender && Bank.balanceOf(buyer) > (amount + fee) && Transaction(txid).getStatus() < 2); | |
Bank.transfer(seller, amount); | |
Bank.transfer(validator, amount); | |
openTxids.removeItem(txid); | |
Transaction(txid).setStatus(3); | |
} | |
// Terminate fraud transaction and report fraud | |
function reportTx(address txid) public { | |
address buyer = Transaction(txid).getBuyer(); | |
address seller = Transaction(txid).getSeller(); | |
address validator = Transaction(txid).getValidator(); | |
uint256 amount = Transaction(txid).getAmount(); | |
uint256 fee = Transaction(txid).getFee(); | |
// msg sender should be buyer | |
require(buyer == msg.sender && Bank.balanceOf(buyer) > fee && Transaction(txid).getStatus() == 1); | |
fraudHistoryPhone[Transaction(txid).getSellerPhone()].push(txid); | |
fraudHistoryAddress[seller].push(txid); | |
fraudHistoryEmail[Transaction(txid).getSellerEmail()].push(txid); | |
openTxids.removeItem(txid); | |
Bank.transfer(validator, amount); | |
Transaction(txid).setStatus(2); | |
} | |
function revertValidation(address txid) public { | |
address buyer = Transaction(txid).getBuyer(); | |
require(buyer == msg.sender && Transaction(txid).getStatus() == 1); | |
Transaction(txid).setStatus(0); | |
} | |
function giveToken(address target) public { | |
Bank.transfer(target, 100); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment