mirror of
https://github.com/status-im/github-oracle.git
synced 2026-08-27 09:51:10 +00:00
@@ -1,5 +1,5 @@
|
||||
# GitHubToken
|
||||
Contract using Oraclize that mint tokens by github commit stats.
|
||||
# GitHubOracle
|
||||
Tokenize github repositories by commits and issues. Accept donations in eth tokens, distribute donations and bounties to code commiters.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -15,8 +15,8 @@ Example: `GitHubOracle.addRepository("ethereans/github-token")`
|
||||
|
||||
### Claiming Tokens
|
||||
Push your commits to github and take the github commitid for each push.
|
||||
Call `GitHubToken.claim("<commitid>")`
|
||||
Example: `GitHubToken.claim("0d3a00941ed72a89f1bf273f17cfd12a0790b82d")`
|
||||
Call `GitHubOracle.claimCommit("<commitid>")`
|
||||
Example: `GitHubOracle.claimCommit("0d3a00941ed72a89f1bf273f17cfd12a0790b82d")`
|
||||
There is no need of specifing the user, this is returned by oraclize call, but the user need to be registered in GitHubOracle in order to claim the tokens.
|
||||
Anyone can call this, and the tokens will be sent to the address registered in user registry.
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* DO NOT USE: under development
|
||||
*/
|
||||
|
||||
contract AbstractBounty {
|
||||
|
||||
uint public constant LOCKED_TIME = 30 days;
|
||||
|
||||
mapping (address => mapping(uint => uint)) deposits;
|
||||
mapping (uint => Issue) issues;
|
||||
|
||||
struct Issue {
|
||||
uint balance;
|
||||
uint unlock;
|
||||
address claimer;
|
||||
bool claimed;
|
||||
}
|
||||
|
||||
modifier only_unlocked(uint num){
|
||||
if(issues[num].unlock == 0 || issues[num].unlock > now) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
modifier only_unclaimed(uint num){
|
||||
if(issues[num].claimed) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
function deposit(uint num)
|
||||
only_unclaimed(num)
|
||||
payable {
|
||||
deposits[msg.sender][num] += msg.value;
|
||||
issues[num].balance += msg.value;
|
||||
}
|
||||
|
||||
function withdraw(uint num)
|
||||
only_unlocked(num)
|
||||
only_unclaimed(num) {
|
||||
uint avaliable = deposits[msg.sender][num];
|
||||
deposits[msg.sender][num] -= avaliable;
|
||||
issues[num].balance -= avaliable;
|
||||
if(!msg.sender.send(avaliable)) throw;
|
||||
}
|
||||
|
||||
function lock(uint num)
|
||||
only_unlocked(num)
|
||||
internal {
|
||||
issues[num].unlock=0;
|
||||
}
|
||||
function unlock(uint num)
|
||||
only_unlocked(num)
|
||||
internal {
|
||||
issues[num].unlock=now+LOCKED_TIME;
|
||||
}
|
||||
|
||||
function claim(uint num)
|
||||
only_unlocked(num)
|
||||
only_unclaimed(num) {
|
||||
issues[num].claimer = msg.sender;
|
||||
issues[num].claimed = true;
|
||||
if(!msg.sender.send(issues[num].balance)) throw;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that oracle github API
|
||||
*
|
||||
* GitHubOracle register users and create GitHubToken contracts
|
||||
* Registration requires user create a gist with only their account address
|
||||
* GitHubOracle will create one GitHubToken contract per repository
|
||||
* GitHubToken mint tokens by commit only for registered users in GitHubOracle
|
||||
* GitHubToken is a LockableCoin, that accept donatations and can be withdrawn by Token Holders
|
||||
* The lookups are done by Oraclize that charge a small fee
|
||||
* The contract itself will never charge any fee
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "lib/oraclize/ethereum-api/oraclizeAPI_0.4.sol";
|
||||
import "./Owned.sol";
|
||||
import "./GitHubToken.sol";
|
||||
import "./GitHubIssues.sol";
|
||||
|
||||
contract GitHubOracle is Owned, usingOraclize {
|
||||
//constant for oraclize user callbacks
|
||||
uint8 constant CLAIM_USER = 0;
|
||||
//constant for oraclize commits callbacks
|
||||
uint8 constant CLAIM_COMMIT = 1;
|
||||
//constant for oraclize issues callbacks
|
||||
uint8 constant UPDATE_ISSUE = 2;
|
||||
//temporary storage enumerating oraclize calls
|
||||
mapping (bytes32 => uint8) claimType;
|
||||
//temporary storage for oraclize commit token claim calls
|
||||
mapping (bytes32 => CommitClaim) commitClaim;
|
||||
//temporary storage for oraclize user register queries
|
||||
mapping (bytes32 => UserClaim) userClaim;
|
||||
//permanent storage of sha3(login) of github users
|
||||
mapping (bytes32 => address) users;
|
||||
//permanent storage of registered repositories
|
||||
mapping (bytes32 => Repository) repositories;
|
||||
//store encrypted values of api access credentials
|
||||
string private credentials = "";
|
||||
//events
|
||||
event UserSet(string githubLogin, address account);
|
||||
event RepositoryAdd(string repository, address token, address issues);
|
||||
|
||||
//stores the address of githubtoken and registered is used for overwriting previous registered
|
||||
struct Repository {
|
||||
GitHubToken token;
|
||||
GitHubIssues issues;
|
||||
bool registered;
|
||||
}
|
||||
|
||||
//stores temporary data for oraclize user register request
|
||||
struct UserClaim {
|
||||
address sender;
|
||||
bytes32 githubid;
|
||||
string login;
|
||||
}
|
||||
//stores temporary data for oraclize repository commit claim
|
||||
struct CommitClaim {
|
||||
bytes32 repository;
|
||||
string commitid;
|
||||
}
|
||||
|
||||
//return the address of a github login
|
||||
function getUserAddress(string _login)
|
||||
external
|
||||
constant
|
||||
returns (address) {
|
||||
return users[sha3(_login)];
|
||||
}
|
||||
|
||||
//oraclize response callback
|
||||
function __callback(bytes32 _ocid, string _result) {
|
||||
if (msg.sender != oraclize_cbAddress()) throw;
|
||||
uint8 callback_type = claimType[_ocid];
|
||||
if(callback_type==CLAIM_USER){
|
||||
if(strCompare(_result,"404: Not Found") != 0){
|
||||
address githubowner = parseAddr(_result);
|
||||
if(userClaim[_ocid].sender == githubowner){
|
||||
_register(userClaim[_ocid].githubid,userClaim[_ocid].login,githubowner);
|
||||
}
|
||||
}
|
||||
delete userClaim[_ocid]; //should always be deleted
|
||||
}else if(callback_type==CLAIM_COMMIT){
|
||||
var (login,total) = extractCommit(_result);
|
||||
repositories[commitClaim[_ocid].repository].token._claim(commitClaim[_ocid].commitid,login,total);
|
||||
delete commitClaim[_ocid]; //should always be deleted
|
||||
}
|
||||
delete claimType[_ocid]; //should always be deleted
|
||||
}
|
||||
|
||||
|
||||
function _register(bytes32 githubid, string login, address githubowner)
|
||||
internal {
|
||||
users[githubid] = githubowner;
|
||||
UserSet(login, githubowner);
|
||||
}
|
||||
|
||||
//register or change a github user ethereum address
|
||||
function register(string _github_user, string _gistid)
|
||||
payable {
|
||||
bytes32 ocid = oraclize_query("URL", strConcat("https://gist.githubusercontent.com/",_github_user,"/",_gistid,"/raw/"));
|
||||
claimType[ocid] = CLAIM_USER;
|
||||
userClaim[ocid] = UserClaim({sender: msg.sender, githubid: sha3(_github_user), login: _github_user});
|
||||
}
|
||||
|
||||
function claimCommit(string _repository, string _commitid)
|
||||
payable {
|
||||
bytes32 ocid = oraclize_query("URL", strConcat(strConcat("json(https://api.github.com/repos/", _repository,"/commits/", _commitid, credentials),").[author,stats].[login,total]"));
|
||||
claimType[ocid] = CLAIM_COMMIT;
|
||||
commitClaim[ocid] = CommitClaim({repository: sha3(_repository), commitid: _commitid });
|
||||
}
|
||||
|
||||
function updateIssueState(string _repository, uint _issueid){
|
||||
throw; // * DO NOT USE: under development
|
||||
//bytes32 ocid = oraclize_query("URL", strConcat(strConcat("json(https://api.github.com/repos/", _repository,"/issues/", parseInt(_issueid), credentials),").[closed_at]"));
|
||||
}
|
||||
|
||||
//creates a new GitHubToken contract to _repository
|
||||
function addRepository(string _repository)
|
||||
returns (GitHubToken) {
|
||||
bytes32 repo = sha3(_repository);
|
||||
if(repositories[repo].registered) throw;
|
||||
repositories[repo] = Repository({
|
||||
token: new GitHubToken(_repository, this),
|
||||
issues: new GitHubIssues(_repository,this),
|
||||
registered: true
|
||||
});
|
||||
RepositoryAdd(_repository, repositories[repo].token, repositories[repo].issues);
|
||||
return repositories[repo].token;
|
||||
}
|
||||
|
||||
//register a contract deployed outside Oracle
|
||||
function addRepository(string _repository, GitHubToken _addr, GitHubIssues _issues)
|
||||
returns (GitHubToken) {
|
||||
bytes32 repo = sha3(_repository);
|
||||
if(repositories[repo].registered || _addr.sha3repository() != repo) throw;
|
||||
repositories[repo] = Repository({token: _addr, issues: _issues, registered: true});
|
||||
RepositoryAdd(_repository, repositories[repo].token, repositories[repo].issues);
|
||||
return repositories[repo].token;
|
||||
}
|
||||
|
||||
//return the contract address of the repository (or 0x0 if none registered)
|
||||
function getRepositoryToken(string _repository)
|
||||
constant
|
||||
returns (GitHubToken) {
|
||||
return repositories[sha3(_repository)].token;
|
||||
}
|
||||
|
||||
|
||||
//extract login name and total of changes in commit
|
||||
function extractCommit(string _s)
|
||||
internal
|
||||
constant
|
||||
returns (string login,uint total) {
|
||||
bytes memory v = bytes(_s);
|
||||
uint comma = 0;
|
||||
uint quot = 0;
|
||||
uint quot2 = 0;
|
||||
for (uint i =0;v.length > i;i++) {
|
||||
if (v[i] == '"'){ //Find first quotation mark
|
||||
quot=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;v.length > i;i++) {
|
||||
if (v[i] == '"') { //find second quotation mark
|
||||
quot2=i;
|
||||
}else if (v[i] == ',') { //find comma
|
||||
comma=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(comma>0 && quot>0 && quot2 >0) {
|
||||
bytes memory user = new bytes(quot2-quot-1);
|
||||
for(i=0; i<user.length; i++){
|
||||
user[i] = v[quot+i+1];
|
||||
}
|
||||
login = string(user); //user
|
||||
for(i=comma+1; i<v.length-1; i++){
|
||||
if ((v[i] >= 48)&&(v[i] <= 57)){ //only ASCII numbers
|
||||
total *= 10;
|
||||
total += uint(v[i]) - 48;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setAPICredentials(string _client_id, string _client_secret)
|
||||
only_owner {
|
||||
credentials = strConcat("?client_id=${[decrypt] ",_client_id,"}&client_secret=${[decrypt] ",_client_secret,"}");
|
||||
}
|
||||
|
||||
function clearAPICredentials()
|
||||
only_owner {
|
||||
credentials = "";
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that mint tokens by github commit stats
|
||||
*
|
||||
* GitHubOracle register users and create GitHubToken contracts
|
||||
* Registration requires user create a gist with only their account address
|
||||
* GitHubOracle will create one GitHubToken contract per repository
|
||||
* GitHubToken mint tokens by commit only for registered users in GitHubOracle
|
||||
* GitHubToken is a LockableCoin, that accept donatations and can be withdrawn by Token Holders
|
||||
* The lookups are done by Oraclize that charge a small fee
|
||||
* The contract itself will never charge any fee
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "lib/ethereans/abstract-token/CollaborationToken.sol";
|
||||
import "GitHubOracle.sol";
|
||||
|
||||
contract GitHubToken is CollaborationToken {
|
||||
|
||||
//stores repository name, used for claim calls
|
||||
string private repository;
|
||||
//stores repository name in sha3, used by GitHubOracle
|
||||
bytes32 public sha3repository;
|
||||
//permanent storage of recipts of all commits
|
||||
mapping (bytes32 => CommitReciept) public commits;
|
||||
//Address of the oracle, used for github login address lookup
|
||||
GitHubOracle public oracle;
|
||||
//claim event
|
||||
event Claim(bytes32 shacommit);
|
||||
|
||||
//stores the total and user, and if claimed (used against double claiming)
|
||||
struct CommitReciept {
|
||||
uint256 total;
|
||||
address user;
|
||||
bool claimed;
|
||||
}
|
||||
|
||||
//protect against double claiming
|
||||
modifier not_claimed(string commitid) {
|
||||
if(isClaimed(commitid)) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
modifier only_oracle {
|
||||
if (msg.sender != address(oracle)) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
function GitHubToken(string _repository, GitHubOracle _oracle) {
|
||||
setAttribute("name", _repository);
|
||||
setDecimalBase(0);
|
||||
oracle = _oracle;
|
||||
repository = _repository;
|
||||
sha3repository = sha3(_repository);
|
||||
}
|
||||
|
||||
//checks if a commit is already claimed
|
||||
function isClaimed(string _commitid)
|
||||
constant
|
||||
returns (bool) {
|
||||
return commits[sha3(_commitid)].claimed;
|
||||
}
|
||||
|
||||
//oracle claim request
|
||||
function _claim(string _commitid, string _login, uint _total)
|
||||
only_oracle {
|
||||
if(_total > 0 && !lock){
|
||||
bytes32 shacommit = sha3(_commitid);
|
||||
address user = oracle.getUserAddress(_login);
|
||||
if(!commits[shacommit].claimed && user != 0x0){
|
||||
commits[shacommit].claimed = true;
|
||||
commits[shacommit].user = user;
|
||||
commits[shacommit].total = _total;
|
||||
mint(user, _total);
|
||||
Claim(shacommit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//claims a commitid
|
||||
function claim(string _commitid)
|
||||
payable
|
||||
not_locked
|
||||
not_claimed(_commitid) {
|
||||
oracle.claimCommit(repository, _commitid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
pragma solidity ^0.4.0;
|
||||
|
||||
library Bytes32Lib {
|
||||
|
||||
function toString(bytes32 self) internal constant returns (string) {
|
||||
bytes memory bytesString = new bytes(32);
|
||||
uint charCount = 0;
|
||||
for (uint j = 0; j < 32; j++) {
|
||||
byte char = byte(bytes32(uint(self) * 2 ** (8 * j)));
|
||||
if (char != 0) {
|
||||
bytesString[charCount] = char;
|
||||
charCount++;
|
||||
}
|
||||
}
|
||||
bytes memory bytesStringTrimmed = new bytes(charCount);
|
||||
for (j = 0; j < charCount; j++) {
|
||||
bytesStringTrimmed[j] = bytesString[j];
|
||||
}
|
||||
return string(bytesStringTrimmed);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
pragma solidity ^0.4.0;
|
||||
|
||||
library IntLib{
|
||||
|
||||
uint constant day = 60*60*24;
|
||||
uint constant week = 60*60*24*7;
|
||||
uint constant month = 60*60*24*30;
|
||||
|
||||
function uint2str(uint i) internal constant returns (string){
|
||||
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(48 + i % 10);
|
||||
i /= 10;
|
||||
}
|
||||
return string(bstr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
library JSONLib {
|
||||
|
||||
function getNextString(bytes _str, uint8 _pos) internal constant returns (string,uint8) {
|
||||
uint8 start = 0;
|
||||
uint8 end = 0;
|
||||
for (;_str.length > _pos; _pos++) {
|
||||
if (_str[_pos] == '"'){ //Found quotation mark
|
||||
if(_str[_pos-1] != '\\'){ //is not escaped
|
||||
end = start == 0 ? 0: _pos;
|
||||
start = start == 0 ? (_pos+1) : start;
|
||||
if(end > 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bytes memory str = new bytes(end-start);
|
||||
for(_pos=0; _pos<str.length; _pos++){
|
||||
str[_pos] = _str[start+_pos];
|
||||
}
|
||||
for(_pos=end+1; _pos<_str.length; _pos++) if (_str[_pos] == ','){ _pos++; break; } //end
|
||||
|
||||
return (string(str),_pos);
|
||||
}
|
||||
|
||||
|
||||
function getNextUInt(bytes _str, uint8 _pos) internal constant returns (uint,uint8) {
|
||||
uint val = 0;
|
||||
for (; _str.length > _pos; _pos++) {
|
||||
if (_str[_pos] == ','){ //Find ends
|
||||
_pos++; break;
|
||||
}else if ((_str[_pos] >= 48)&&(_str[_pos] <= 57)){ //only ASCII numbers
|
||||
val *= 10;
|
||||
val += uint(_str[_pos]) - 48;
|
||||
}
|
||||
}
|
||||
return (val,_pos);
|
||||
}
|
||||
|
||||
function getNextAddr(bytes _str, uint8 _pos) internal constant returns (address, uint8){
|
||||
uint160 iaddr = 0;
|
||||
for(;_str.length > _pos; _pos++){
|
||||
if (_str[_pos] == '0'){
|
||||
if (_str[_pos+1] == 'x'){
|
||||
for (_pos=_pos+2; _pos<2+2*20; _pos+=2){
|
||||
iaddr *= 256;
|
||||
iaddr += (uint160(hexVal(uint160(_str[_pos])))*16+uint160(hexVal(uint160(_str[_pos+1]))));
|
||||
}
|
||||
_pos++;
|
||||
break;
|
||||
}
|
||||
}else if (_str[_pos] == ','){
|
||||
_pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (address(iaddr),_pos);
|
||||
}
|
||||
|
||||
function hexVal(uint val) internal constant returns (uint){
|
||||
//return val - (val < 58 ? 48 : 55); //uppercase
|
||||
//return val - (val < 58 ? 48 : 87); //lowercase
|
||||
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87)); //both
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
pragma solidity ^0.4.9;
|
||||
|
||||
|
||||
library StringLib {
|
||||
|
||||
function hexVal(uint val) internal constant returns (uint){
|
||||
//return val - (val < 58 ? 48 : 55); //uppercase
|
||||
//return val - (val < 58 ? 48 : 87); //lowercase
|
||||
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87)); //both
|
||||
}
|
||||
|
||||
function toBytes32(string memory source) constant returns (bytes32 result) {
|
||||
assembly {
|
||||
result := mload(add(source, 32))
|
||||
}
|
||||
}
|
||||
function parseBytes20(string self)
|
||||
constant returns (bytes20 bs) {
|
||||
bytes memory h = bytes(self);
|
||||
if (h.length>>1 != 20)
|
||||
throw;// new Exception("The binary need 20 digits");
|
||||
for (uint i = 0; i < 20; ++i)
|
||||
{
|
||||
bs |= bytes20((byte)((hexVal(uint(h[i << 1])) << 4) + (hexVal(uint(h[(i << 1) + 1])))))>>(8*i);
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
function parseBytes32(string self)
|
||||
constant returns (bytes32 bs) {
|
||||
bytes memory h = bytes(self);
|
||||
if (h.length>>1 != 32)
|
||||
throw;// new Exception("The binary need 20 digits");
|
||||
for (uint i = 0; i < 32; ++i)
|
||||
{
|
||||
bs |= bytes32((byte)((hexVal(uint(h[i << 1])) << 4) + (hexVal(uint(h[(i << 1) + 1])))))>>(8*i);
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
function parseAddr(string self) constant returns (address){
|
||||
bytes memory tmp = bytes(self);
|
||||
uint iaddr = 0;
|
||||
for (uint i=2; i<2+2*20; i+=2){
|
||||
iaddr += hexVal(uint(tmp[i]))*16+hexVal(uint(tmp[i+1]));
|
||||
}
|
||||
return address(iaddr);
|
||||
}
|
||||
|
||||
function compare(string self, string _b) constant returns (int) {
|
||||
bytes memory a = bytes(self);
|
||||
bytes memory b = bytes(_b);
|
||||
uint minLength = a.length;
|
||||
if (b.length < minLength) minLength = b.length;
|
||||
for (uint i = 0; i < minLength; i ++)
|
||||
if (a[i] < b[i])
|
||||
return -1;
|
||||
else if (a[i] > b[i])
|
||||
return 1;
|
||||
if (a.length < b.length)
|
||||
return -1;
|
||||
else if (a.length > b.length)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
function indexOf(string _haystack, string _needle) constant returns (int) {
|
||||
bytes memory h = bytes(_haystack);
|
||||
bytes memory n = bytes(_needle);
|
||||
if(h.length < 1 || n.length < 1 || (n.length > h.length))
|
||||
return -1;
|
||||
else if(h.length > (2**128 -1))
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
uint subindex = 0;
|
||||
for (uint i = 0; i < h.length; i ++)
|
||||
{
|
||||
if (h[i] == n[0])
|
||||
{
|
||||
subindex = 1;
|
||||
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex])
|
||||
{
|
||||
subindex++;
|
||||
}
|
||||
if(subindex == n.length)
|
||||
return int(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// parseInt
|
||||
function parseInt(string self) constant returns (uint) {
|
||||
return parseInt(self, 0);
|
||||
}
|
||||
|
||||
// parseInt(parseFloat*10^_b)
|
||||
function parseInt(string self, uint _b) constant returns (uint) {
|
||||
bytes memory bresult = bytes(self);
|
||||
uint mint = 0;
|
||||
bool decimals = false;
|
||||
for (uint i=0; i<bresult.length; i++){
|
||||
if ((bresult[i] >= 48)&&(bresult[i] <= 57)){
|
||||
if (decimals){
|
||||
if (_b == 0) break;
|
||||
else _b--;
|
||||
}
|
||||
mint *= 10;
|
||||
mint += uint(bresult[i]) - 48;
|
||||
} else if (bresult[i] == 46) decimals = true;
|
||||
}
|
||||
if (_b > 0) mint *= 10**_b;
|
||||
return mint;
|
||||
}
|
||||
|
||||
|
||||
function concat(string self, string _b, string _c, string _d, string _e) internal constant returns (string) {
|
||||
bytes memory _ba = bytes(self);
|
||||
bytes memory _bb = bytes(_b);
|
||||
bytes memory _bc = bytes(_c);
|
||||
bytes memory _bd = bytes(_d);
|
||||
bytes memory _be = bytes(_e);
|
||||
string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
|
||||
bytes memory babcde = bytes(abcde);
|
||||
uint k = 0;
|
||||
for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
|
||||
for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
|
||||
for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
|
||||
for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
|
||||
for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
|
||||
return string(babcde);
|
||||
}
|
||||
|
||||
function concat(string self, string _b, string _c, string _d) internal constant returns (string) {
|
||||
return concat(self, _b, _c, _d, "");
|
||||
}
|
||||
|
||||
function concat(string self, string _b, string _c) internal constant returns (string) {
|
||||
return concat(self, _b, _c, "", "");
|
||||
}
|
||||
|
||||
function concat(string self, string _b) internal constant returns (string) {
|
||||
return concat(self, _b, "", "", "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../../../abstract-token/contracts/
|
||||
@@ -0,0 +1,10 @@
|
||||
pragma solidity ^0.4.9;
|
||||
|
||||
|
||||
contract Bank {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
contract Secret {
|
||||
|
||||
/**
|
||||
* @var token (stores the current token)
|
||||
*/
|
||||
bytes32 private token;
|
||||
mapping (bytes32 => bool) tokens;
|
||||
/**
|
||||
* @param secret the revealed secret
|
||||
* @param _token the keccak256 hash of next secret
|
||||
*/
|
||||
modifier secret(bytes32 secret, bytes32 _token){
|
||||
setToken(secret,_token);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _token the keccak256 hash of next secret
|
||||
*/
|
||||
function Secret(bytes32 _token){
|
||||
token = _token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice secret use current token to replace it by new _token
|
||||
* @param secret the revealed secret
|
||||
* @param _token the keccak256 hash of next secret
|
||||
*/
|
||||
function setToken(bytes32 secret, bytes32 _token){
|
||||
if(tokens[_token] == true) throw;
|
||||
if(keccak256(secret) != token) throw;
|
||||
tokens[token] = true;
|
||||
token = _token;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* AbstractToken ECR20-compliant token contract
|
||||
* Child should implement initial supply or minting and overwite base
|
||||
* Based on BasicCoin by Parity Team (Ethcore), 2016.
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under the Apache Licence 2.
|
||||
*/
|
||||
|
||||
import "./Token.sol";
|
||||
|
||||
// AbstractToken, ECR20 tokens that all belong to the owner for sending around
|
||||
contract AbstractToken is Token {
|
||||
|
||||
uint256 private decimalBase = 0;
|
||||
mapping (bytes => bytes) private attributes;
|
||||
mapping (address => Account) private accounts;
|
||||
event Base(uint256 decimalBase);
|
||||
event SetAttribute(string name, string value);
|
||||
event Mint(address to, uint256 value);
|
||||
event Destroy(address from, uint256 value);
|
||||
|
||||
|
||||
struct Decimal {
|
||||
uint256 value;
|
||||
uint256 base;
|
||||
}
|
||||
|
||||
struct Account {
|
||||
Decimal balance;
|
||||
mapping (address => Decimal) allowanceOf;
|
||||
}
|
||||
|
||||
// the balance should be available
|
||||
modifier when_owns(address _owner, uint256 _amount) {
|
||||
if (balanceOf(_owner) < _amount) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
// an allowance should be available
|
||||
modifier when_has_allowance(address _owner, address _spender, uint256 _amount) {
|
||||
if (allowance(_owner,_spender) < _amount) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
//correct base and balance if needed
|
||||
function _safeDecimals(Decimal _decimal)
|
||||
internal
|
||||
constant returns(Decimal){
|
||||
if(_decimal.base != decimalBase) {
|
||||
if(_decimal.value > 0){
|
||||
int256 baseDiff = int256(_decimal.base) - int256(decimalBase);
|
||||
if(baseDiff > 0){
|
||||
_decimal.value *= 10**uint256(baseDiff);
|
||||
}else if(baseDiff < 0){
|
||||
uint256 oldv = _decimal.value;
|
||||
uint256 newv = _decimal.value/(10**uint256(baseDiff*-1));
|
||||
_decimal.value = oldv > newv ? newv : 0;
|
||||
}
|
||||
}
|
||||
_decimal.base = decimalBase; //update base of account
|
||||
}
|
||||
return _decimal;
|
||||
}
|
||||
|
||||
//_safeDecimals wrapper for safe add;
|
||||
function _safeDecimalsAdd(Decimal _decimal, uint256 _value)
|
||||
internal
|
||||
constant returns(Decimal){
|
||||
_decimal = _safeDecimals(_decimal);
|
||||
_decimal.value += _value;
|
||||
return _decimal;
|
||||
}
|
||||
|
||||
function _safeDecimalsSub(Decimal _decimal, uint256 _value)
|
||||
internal
|
||||
constant returns(Decimal){
|
||||
_decimal = _safeDecimals(_decimal);
|
||||
_decimal.value -= _value;
|
||||
return _decimal;
|
||||
}
|
||||
//_safeDecimals wrapper for safe sub;
|
||||
function base()
|
||||
constant returns(uint256) {
|
||||
return decimalBase;
|
||||
}
|
||||
|
||||
//child may override this function to trigger changes in balance dependent storage
|
||||
function _balanceUpdated(address _from)
|
||||
internal {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the decimal base
|
||||
* lowereing base remove precision of most significant digits
|
||||
* rising base remove precision of last significant digits
|
||||
*/
|
||||
function setDecimalBase(uint256 _decimalBase)
|
||||
internal {
|
||||
Base(_decimalBase);
|
||||
decimalBase = _decimalBase;
|
||||
}
|
||||
|
||||
//sets attributes for wallet usage
|
||||
function setAttribute(string _name, string _value)
|
||||
internal {
|
||||
SetAttribute(_name,_value);
|
||||
if (bytes(_value).length > 0) attributes[bytes(_name)] = bytes(_value);
|
||||
else delete attributes[bytes(_name)];
|
||||
}
|
||||
|
||||
//read an attribute from storage
|
||||
function getAttribute(string _name)
|
||||
constant returns (string){
|
||||
return string(attributes[bytes(_name)]);
|
||||
}
|
||||
|
||||
// add tokens to a balance
|
||||
function _mint(address _to, uint256 _value)
|
||||
internal {
|
||||
if (totalSupply + _value < totalSupply) throw; //overflow: maximum totalSupply in the current base;
|
||||
Mint(_to, _value);
|
||||
totalSupply += _value;
|
||||
accounts[_to].balance = _safeDecimalsAdd(accounts[_to].balance,_value);
|
||||
_balanceUpdated(_to);
|
||||
}
|
||||
|
||||
// remove tokens from a balance
|
||||
function _destroy(address _from, uint256 _value)
|
||||
internal {
|
||||
Destroy(_from, _value);
|
||||
totalSupply -= _value;
|
||||
accounts[_from].balance = _safeDecimalsSub(accounts[_from].balance,_value);
|
||||
if(accounts[_from].balance.value == 0){
|
||||
delete accounts[_from]; //to reduce gas in mapping accounts
|
||||
}
|
||||
_balanceUpdated(_from);
|
||||
}
|
||||
|
||||
// balance of a specific address
|
||||
function balanceOf(address _who)
|
||||
constant
|
||||
returns (uint256) {
|
||||
return _safeDecimals(accounts[_who].balance).value;
|
||||
}
|
||||
|
||||
// transfer
|
||||
function transfer(address _to, uint256 _value)
|
||||
when_owns(msg.sender, _value)
|
||||
returns (bool) {
|
||||
Transfer(msg.sender, _to, _value);
|
||||
accounts[msg.sender].balance = _safeDecimalsSub(accounts[msg.sender].balance, _value);
|
||||
accounts[_to].balance = _safeDecimalsAdd(accounts[_to].balance, _value);
|
||||
_balanceUpdated(msg.sender);
|
||||
_balanceUpdated(_to);
|
||||
return true;
|
||||
}
|
||||
|
||||
// transfer via allowance
|
||||
function transferFrom(address _from, address _to, uint256 _value)
|
||||
when_owns(_from, _value)
|
||||
when_has_allowance(_from, msg.sender, _value)
|
||||
returns (bool) {
|
||||
Transfer(_from, _to, _value);
|
||||
accounts[_from].allowanceOf[msg.sender] = _safeDecimalsSub(accounts[_from].allowanceOf[msg.sender], _value);
|
||||
accounts[_from].balance = _safeDecimalsSub(accounts[msg.sender].balance, _value);
|
||||
accounts[_to].balance = _safeDecimalsAdd(accounts[_to].balance, _value);
|
||||
_balanceUpdated(_from);
|
||||
_balanceUpdated(_to);
|
||||
return true;
|
||||
}
|
||||
|
||||
// set allowance
|
||||
function approve(address _spender, uint256 _totalAllowed)
|
||||
returns (bool) {
|
||||
Approval(msg.sender, _spender, _totalAllowed);
|
||||
accounts[msg.sender].allowanceOf[_spender].value = _totalAllowed;
|
||||
accounts[msg.sender].allowanceOf[_spender].base = decimalBase;
|
||||
if(_totalAllowed == 0){
|
||||
delete accounts[msg.sender].allowanceOf[_spender]; //lower gas in interactions
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// available allowance
|
||||
function allowance(address _owner, address _spender)
|
||||
constant
|
||||
returns (uint256) {
|
||||
return _safeDecimals(accounts[_owner].allowanceOf[_spender]).value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
pragma solidity ^0.4.0;
|
||||
|
||||
/**
|
||||
* Abstract contract used for recieving donations or profits
|
||||
* Withdraw is divided by total tokens each account owns
|
||||
* Unlock period allows transfers
|
||||
* Lock period allow withdraws
|
||||
* Child contract that implement minting should use modifier not_locked in minting function
|
||||
* Inspired by ProfitContainer and Lockable by vDice
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "./AbstractToken.sol";
|
||||
|
||||
contract CollaborationToken is AbstractToken {
|
||||
//creation time, defined when contract is created
|
||||
uint256 public creationTime = now;
|
||||
//time constants, defines epoch size and periods
|
||||
uint256 public constant UNLOCKED_TIME = 25 days;
|
||||
uint256 public constant LOCKED_TIME = 5 days;
|
||||
uint256 public constant EPOCH_LENGTH = UNLOCKED_TIME + LOCKED_TIME;
|
||||
//current epoch constant formula, recalculated in any contract call
|
||||
uint256 public constant CURRENT_EPOCH = (now - creationTime) / EPOCH_LENGTH + 1;
|
||||
//next lock constant formula, recalculated in any contract call
|
||||
uint256 public constant NEXT_LOCK = (creationTime + CURRENT_EPOCH * UNLOCKED_TIME) + (CURRENT_EPOCH - 1) * LOCKED_TIME;
|
||||
//used for calculating balance and for checking if account withdrawn
|
||||
uint256 public currentPayEpoch;
|
||||
//stores the balance from the lock time
|
||||
uint256 public epochBalance;
|
||||
//stores lock state, used for events
|
||||
bool public lock;
|
||||
//used for hecking if account withdrawn
|
||||
mapping (address => uint) lastPaidOutEpoch;
|
||||
//events
|
||||
event Withdrawn(address tokenHolder, uint256 amountPaidOut);
|
||||
event Deposited(address donator,uint256 value);
|
||||
event Locked();
|
||||
event Unlocked();
|
||||
|
||||
//checks if not locked and call event on change
|
||||
modifier not_locked {
|
||||
if (NEXT_LOCK < now) {
|
||||
if (lock) throw;
|
||||
lock = true;
|
||||
Locked();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (lock) {
|
||||
lock = false;
|
||||
Unlocked();
|
||||
}
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
//checks if is locked and call event on change
|
||||
modifier locked {
|
||||
if (NEXT_LOCK < now) {
|
||||
if (!lock){
|
||||
lock = true;
|
||||
Locked();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!lock) throw;
|
||||
lock = false;
|
||||
Unlocked();
|
||||
return;
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
//update the balance and payout epoch
|
||||
modifier update_epoch {
|
||||
if(currentPayEpoch < CURRENT_EPOCH) {
|
||||
currentPayEpoch = CURRENT_EPOCH;
|
||||
epochBalance = this.balance;
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
//checks if user already withdrawn
|
||||
modifier not_paid {
|
||||
if (lastPaidOutEpoch[msg.sender] == currentPayEpoch) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
//check overflow in multiply
|
||||
modifier safe_multiply(uint256 _a, uint256 _b) {
|
||||
if (!(_b == 0 || ((_a * _b) / _b) == _a)) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
//allow deposit and call event
|
||||
function ()
|
||||
payable {
|
||||
Deposited(msg.sender, msg.value);
|
||||
}
|
||||
|
||||
//withdraw if locked and not paid, updates epoch
|
||||
function withdrawal()
|
||||
external
|
||||
locked
|
||||
update_epoch
|
||||
not_paid
|
||||
safe_multiply(balanceOf(msg.sender), epochBalance) {
|
||||
uint256 _currentEpoch = CURRENT_EPOCH;
|
||||
uint256 _tokenBalance = balanceOf(msg.sender);
|
||||
uint256 _totalSupply = totalSupply;
|
||||
if (this.balance == 0 || _tokenBalance == 0) throw;
|
||||
lastPaidOutEpoch[msg.sender] = currentPayEpoch;
|
||||
uint256 amountToPayOut = (_tokenBalance * epochBalance) / _totalSupply;
|
||||
if(!msg.sender.send(amountToPayOut)) {
|
||||
throw;
|
||||
}
|
||||
Withdrawn(msg.sender, amountToPayOut);
|
||||
}
|
||||
|
||||
//if this coin owns tokens of other lockablecoin, allow withdraw
|
||||
function withdrawalFrom(CollaborationToken _otherCollaborationToken) {
|
||||
_otherCollaborationToken.withdrawal();
|
||||
}
|
||||
|
||||
//return expected payout in lock or estimated when not locked
|
||||
function expectedPayout(address _tokenHolder)
|
||||
external
|
||||
constant
|
||||
returns (uint256 payout) {
|
||||
if (now < NEXT_LOCK) //unlocked, estimate
|
||||
payout = (balanceOf(_tokenHolder) * this.balance) / totalSupply;
|
||||
else
|
||||
payout = (balanceOf(_tokenHolder) * epochBalance) / totalSupply;
|
||||
}
|
||||
|
||||
//overwrite not allow transfer during lock
|
||||
function transfer(address _to, uint256 _value)
|
||||
not_locked
|
||||
returns (bool ok) {
|
||||
return super.transfer(_to,_value);
|
||||
}
|
||||
|
||||
//overwrite not allow transfer during lock
|
||||
function transferFrom(address _from, address _to, uint256 _value)
|
||||
not_locked
|
||||
returns (bool ok) {
|
||||
return super.transferFrom(_from,_to,_value);
|
||||
}
|
||||
|
||||
//overwrite not allow transfer during lock
|
||||
function approve(address _spender, uint256 _value)
|
||||
returns (bool ok) {
|
||||
return super.approve(_spender,_value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
pragma solidity ^0.4.1;
|
||||
|
||||
/**
|
||||
* Mintable Collaboration coin with register of reason of minting
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "../management/Owned.sol";
|
||||
import "./CollaborationToken.sol";
|
||||
|
||||
contract JustifiedCollaborationToken is CollaborationToken, Owned {
|
||||
event Claim(bytes32 _data);
|
||||
mapping (bytes32 => Receipt) public receipts;
|
||||
mapping (address => bool) public minters;
|
||||
|
||||
// storage of minting reason
|
||||
struct Receipt {
|
||||
address beneficiary;
|
||||
uint256 value;
|
||||
bool claimed;
|
||||
}
|
||||
|
||||
function claim(address _beneficiary, uint256 _value, bytes32 _data)
|
||||
not_locked
|
||||
only_owner {
|
||||
if(receipts[_data].claimed) throw;
|
||||
receipts[_data] = Receipt ({beneficiary: _beneficiary, value: _value, claimed: true});
|
||||
_mint(_beneficiary,_value);
|
||||
Claim(_data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
// ECR20 standard token interface
|
||||
|
||||
contract Token {
|
||||
uint256 public totalSupply;
|
||||
function balanceOf(address who) constant returns (uint256);
|
||||
function allowance(address owner, address spender) constant returns (uint256);
|
||||
function transfer(address to, uint256 value) returns (bool ok);
|
||||
function transferFrom(address from, address to, uint256 value) returns (bool ok);
|
||||
function approve(address spender, uint256 value) returns (bool ok);
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
pragma solidity ^0.4.0;
|
||||
|
||||
/**
|
||||
* WrappedEthToken is a contract that creates 1 token por eth deposited.
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "./AbstractToken.sol";
|
||||
|
||||
contract WrappedEthToken is AbstractToken {
|
||||
|
||||
//Minting is by depositing in the contract
|
||||
function ()
|
||||
payable {
|
||||
deposit();
|
||||
}
|
||||
|
||||
function deposit()
|
||||
payable {
|
||||
_mint(msg.sender,msg.value);
|
||||
}
|
||||
|
||||
function withdraw(uint256 _amount)
|
||||
when_owns (msg.sender, _amount) {
|
||||
_destroy(msg.sender, _amount);
|
||||
if(!msg.sender.send(_amount)) throw;
|
||||
}
|
||||
|
||||
function withdraw() {
|
||||
withdraw(balanceOf(msg.sender));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../../../oraclize/ethereum-api
|
||||
@@ -0,0 +1,521 @@
|
||||
// <ORACLIZE_API>
|
||||
/*
|
||||
Copyright (c) 2015-2016 Oraclize SRL
|
||||
Copyright (c) 2016 Oraclize LTD
|
||||
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.0;//please import oraclizeAPI_pre0.4.sol when solidity < 0.4.0
|
||||
|
||||
contract OraclizeI {
|
||||
address public cbAddress;
|
||||
function query(uint _timestamp, string _datasource, string _arg) payable returns (bytes32 _id);
|
||||
function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit) payable returns (bytes32 _id);
|
||||
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2) payable returns (bytes32 _id);
|
||||
function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit) payable returns (bytes32 _id);
|
||||
function queryN(uint _timestamp, string _datasource, bytes _argN) payable returns (bytes32 _id);
|
||||
function queryN_withGasLimit(uint _timestamp, string _datasource, bytes _argN, uint _gaslimit) payable returns (bytes32 _id);
|
||||
function getPrice(string _datasource) returns (uint _dsprice);
|
||||
function getPrice(string _datasource, uint gaslimit) returns (uint _dsprice);
|
||||
function useCoupon(string _coupon);
|
||||
function setProofType(byte _proofType);
|
||||
function setConfig(bytes32 _config);
|
||||
function setCustomGasPrice(uint _gasPrice);
|
||||
}
|
||||
contract OraclizeAddrResolverI {
|
||||
function getAddress() returns (address _addr);
|
||||
}
|
||||
contract usingOraclize {
|
||||
uint constant day = 60*60*24;
|
||||
uint constant week = 60*60*24*7;
|
||||
uint constant month = 60*60*24*30;
|
||||
byte constant proofType_NONE = 0x00;
|
||||
byte constant proofType_TLSNotary = 0x10;
|
||||
byte constant proofStorage_IPFS = 0x01;
|
||||
uint8 constant networkID_auto = 0;
|
||||
uint8 constant networkID_mainnet = 1;
|
||||
uint8 constant networkID_testnet = 2;
|
||||
uint8 constant networkID_morden = 2;
|
||||
uint8 constant networkID_consensys = 161;
|
||||
|
||||
OraclizeAddrResolverI OAR;
|
||||
|
||||
OraclizeI oraclize;
|
||||
modifier oraclizeAPI {
|
||||
if((address(OAR)==0)||(getCodeSize(address(OAR))==0)) oraclize_setNetwork(networkID_auto);
|
||||
oraclize = OraclizeI(OAR.getAddress());
|
||||
_;
|
||||
}
|
||||
modifier coupon(string code){
|
||||
oraclize = OraclizeI(OAR.getAddress());
|
||||
oraclize.useCoupon(code);
|
||||
_;
|
||||
}
|
||||
|
||||
function oraclize_setNetwork(uint8 networkID) internal returns(bool){
|
||||
if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet
|
||||
OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
|
||||
return true;
|
||||
}
|
||||
if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){ //ropsten testnet
|
||||
OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1);
|
||||
return true;
|
||||
}
|
||||
if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){ //kovan testnet
|
||||
OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e);
|
||||
return true;
|
||||
}
|
||||
if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475)>0){ //ethereum-bridge
|
||||
OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
|
||||
return true;
|
||||
}
|
||||
if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF)>0){ //ether.camp ide
|
||||
OAR = OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF);
|
||||
return true;
|
||||
}
|
||||
if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA)>0){ //browser-solidity
|
||||
OAR = OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function __callback(bytes32 myid, string result) {
|
||||
__callback(myid, result, new bytes(0));
|
||||
}
|
||||
function __callback(bytes32 myid, string result, bytes proof) {
|
||||
}
|
||||
|
||||
function oraclize_getPrice(string datasource) oraclizeAPI internal returns (uint){
|
||||
return oraclize.getPrice(datasource);
|
||||
}
|
||||
|
||||
function oraclize_getPrice(string datasource, uint gaslimit) oraclizeAPI internal returns (uint){
|
||||
return oraclize.getPrice(datasource, gaslimit);
|
||||
}
|
||||
|
||||
function oraclize_query(string datasource, string arg) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource);
|
||||
if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
|
||||
return oraclize.query.value(price)(0, datasource, arg);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string arg) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource);
|
||||
if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
|
||||
return oraclize.query.value(price)(timestamp, datasource, arg);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource, gaslimit);
|
||||
if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
|
||||
return oraclize.query_withGasLimit.value(price)(timestamp, datasource, arg, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource, gaslimit);
|
||||
if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
|
||||
return oraclize.query_withGasLimit.value(price)(0, datasource, arg, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource);
|
||||
if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
|
||||
return oraclize.query2.value(price)(0, datasource, arg1, arg2);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource);
|
||||
if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
|
||||
return oraclize.query2.value(price)(timestamp, datasource, arg1, arg2);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource, gaslimit);
|
||||
if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
|
||||
return oraclize.query2_withGasLimit.value(price)(timestamp, datasource, arg1, arg2, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource, gaslimit);
|
||||
if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
|
||||
return oraclize.query2_withGasLimit.value(price)(0, datasource, arg1, arg2, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[] argN) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource);
|
||||
if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
|
||||
bytes memory args = stra2cbor(argN);
|
||||
return oraclize.queryN.value(price)(0, datasource, args);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[] argN) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource);
|
||||
if (price > 1 ether + tx.gasprice*200000) return 0; // unexpectedly high price
|
||||
bytes memory args = stra2cbor(argN);
|
||||
return oraclize.queryN.value(price)(timestamp, datasource, args);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource, gaslimit);
|
||||
if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
|
||||
bytes memory args = stra2cbor(argN);
|
||||
return oraclize.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
|
||||
uint price = oraclize.getPrice(datasource, gaslimit);
|
||||
if (price > 1 ether + tx.gasprice*gaslimit) return 0; // unexpectedly high price
|
||||
bytes memory args = stra2cbor(argN);
|
||||
return oraclize.queryN_withGasLimit.value(price)(0, datasource, args, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[1] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](1);
|
||||
dynargs[0] = args[0];
|
||||
return oraclize_query(datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[1] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](1);
|
||||
dynargs[0] = args[0];
|
||||
return oraclize_query(timestamp, datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](1);
|
||||
dynargs[0] = args[0];
|
||||
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](1);
|
||||
dynargs[0] = args[0];
|
||||
return oraclize_query(datasource, dynargs, gaslimit);
|
||||
}
|
||||
|
||||
function oraclize_query(string datasource, string[2] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](2);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
return oraclize_query(datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[2] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](2);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
return oraclize_query(timestamp, datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](2);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](2);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
return oraclize_query(datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[3] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](3);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
return oraclize_query(datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[3] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](3);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
return oraclize_query(timestamp, datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](3);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](3);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
return oraclize_query(datasource, dynargs, gaslimit);
|
||||
}
|
||||
|
||||
function oraclize_query(string datasource, string[4] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](4);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
return oraclize_query(datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[4] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](4);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
return oraclize_query(timestamp, datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](4);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](4);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
return oraclize_query(datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[5] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](5);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
dynargs[4] = args[4];
|
||||
return oraclize_query(datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[5] args) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](5);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
dynargs[4] = args[4];
|
||||
return oraclize_query(timestamp, datasource, dynargs);
|
||||
}
|
||||
function oraclize_query(uint timestamp, string datasource, string[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](5);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
dynargs[4] = args[4];
|
||||
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
|
||||
}
|
||||
function oraclize_query(string datasource, string[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
|
||||
string[] memory dynargs = new string[](5);
|
||||
dynargs[0] = args[0];
|
||||
dynargs[1] = args[1];
|
||||
dynargs[2] = args[2];
|
||||
dynargs[3] = args[3];
|
||||
dynargs[4] = args[4];
|
||||
return oraclize_query(datasource, dynargs, gaslimit);
|
||||
}
|
||||
|
||||
function oraclize_cbAddress() oraclizeAPI internal returns (address){
|
||||
return oraclize.cbAddress();
|
||||
}
|
||||
function oraclize_setProof(byte proofP) oraclizeAPI internal {
|
||||
return oraclize.setProofType(proofP);
|
||||
}
|
||||
function oraclize_setCustomGasPrice(uint gasPrice) oraclizeAPI internal {
|
||||
return oraclize.setCustomGasPrice(gasPrice);
|
||||
}
|
||||
function oraclize_setConfig(bytes32 config) oraclizeAPI internal {
|
||||
return oraclize.setConfig(config);
|
||||
}
|
||||
|
||||
function getCodeSize(address _addr) constant internal returns(uint _size) {
|
||||
assembly {
|
||||
_size := extcodesize(_addr)
|
||||
}
|
||||
}
|
||||
|
||||
function parseAddr(string _a) internal returns (address){
|
||||
bytes memory tmp = bytes(_a);
|
||||
uint160 iaddr = 0;
|
||||
uint160 b1;
|
||||
uint160 b2;
|
||||
for (uint i=2; i<2+2*20; i+=2){
|
||||
iaddr *= 256;
|
||||
b1 = uint160(tmp[i]);
|
||||
b2 = uint160(tmp[i+1]);
|
||||
if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87;
|
||||
else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48;
|
||||
if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87;
|
||||
else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48;
|
||||
iaddr += (b1*16+b2);
|
||||
}
|
||||
return address(iaddr);
|
||||
}
|
||||
|
||||
function strCompare(string _a, string _b) internal returns (int) {
|
||||
bytes memory a = bytes(_a);
|
||||
bytes memory b = bytes(_b);
|
||||
uint minLength = a.length;
|
||||
if (b.length < minLength) minLength = b.length;
|
||||
for (uint i = 0; i < minLength; i ++)
|
||||
if (a[i] < b[i])
|
||||
return -1;
|
||||
else if (a[i] > b[i])
|
||||
return 1;
|
||||
if (a.length < b.length)
|
||||
return -1;
|
||||
else if (a.length > b.length)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
function indexOf(string _haystack, string _needle) internal returns (int) {
|
||||
bytes memory h = bytes(_haystack);
|
||||
bytes memory n = bytes(_needle);
|
||||
if(h.length < 1 || n.length < 1 || (n.length > h.length))
|
||||
return -1;
|
||||
else if(h.length > (2**128 -1))
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
uint subindex = 0;
|
||||
for (uint i = 0; i < h.length; i ++)
|
||||
{
|
||||
if (h[i] == n[0])
|
||||
{
|
||||
subindex = 1;
|
||||
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex])
|
||||
{
|
||||
subindex++;
|
||||
}
|
||||
if(subindex == n.length)
|
||||
return int(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function strConcat(string _a, string _b, string _c, string _d, string _e) internal returns (string) {
|
||||
bytes memory _ba = bytes(_a);
|
||||
bytes memory _bb = bytes(_b);
|
||||
bytes memory _bc = bytes(_c);
|
||||
bytes memory _bd = bytes(_d);
|
||||
bytes memory _be = bytes(_e);
|
||||
string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
|
||||
bytes memory babcde = bytes(abcde);
|
||||
uint k = 0;
|
||||
for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
|
||||
for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
|
||||
for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
|
||||
for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
|
||||
for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
|
||||
return string(babcde);
|
||||
}
|
||||
|
||||
function strConcat(string _a, string _b, string _c, string _d) internal returns (string) {
|
||||
return strConcat(_a, _b, _c, _d, "");
|
||||
}
|
||||
|
||||
function strConcat(string _a, string _b, string _c) internal returns (string) {
|
||||
return strConcat(_a, _b, _c, "", "");
|
||||
}
|
||||
|
||||
function strConcat(string _a, string _b) internal returns (string) {
|
||||
return strConcat(_a, _b, "", "", "");
|
||||
}
|
||||
|
||||
// parseInt
|
||||
function parseInt(string _a) internal returns (uint) {
|
||||
return parseInt(_a, 0);
|
||||
}
|
||||
|
||||
// parseInt(parseFloat*10^_b)
|
||||
function parseInt(string _a, uint _b) internal returns (uint) {
|
||||
bytes memory bresult = bytes(_a);
|
||||
uint mint = 0;
|
||||
bool decimals = false;
|
||||
for (uint i=0; i<bresult.length; i++){
|
||||
if ((bresult[i] >= 48)&&(bresult[i] <= 57)){
|
||||
if (decimals){
|
||||
if (_b == 0) break;
|
||||
else _b--;
|
||||
}
|
||||
mint *= 10;
|
||||
mint += uint(bresult[i]) - 48;
|
||||
} else if (bresult[i] == 46) decimals = true;
|
||||
}
|
||||
if (_b > 0) mint *= 10**_b;
|
||||
return mint;
|
||||
}
|
||||
|
||||
function uint2str(uint i) internal returns (string){
|
||||
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(48 + i % 10);
|
||||
i /= 10;
|
||||
}
|
||||
return string(bstr);
|
||||
}
|
||||
|
||||
function stra2cbor(string[] arr) internal returns (bytes) {
|
||||
uint arrlen = arr.length;
|
||||
|
||||
// get correct cbor output length
|
||||
uint outputlen = 0;
|
||||
bytes[] memory elemArray = new bytes[](arrlen);
|
||||
for (uint i = 0; i < arrlen; i++) {
|
||||
elemArray[i] = (bytes(arr[i]));
|
||||
outputlen += elemArray[i].length + (elemArray[i].length - 1)/23 + 3; //+3 accounts for paired identifier types
|
||||
}
|
||||
uint ctr = 0;
|
||||
uint cborlen = arrlen + 0x80;
|
||||
outputlen += byte(cborlen).length;
|
||||
bytes memory res = new bytes(outputlen);
|
||||
|
||||
while (byte(cborlen).length > ctr) {
|
||||
res[ctr] = byte(cborlen)[ctr];
|
||||
ctr++;
|
||||
}
|
||||
for (i = 0; i < arrlen; i++) {
|
||||
res[ctr] = 0x5F;
|
||||
ctr++;
|
||||
for (uint x = 0; x < elemArray[i].length; x++) {
|
||||
// if there's a bug with larger strings, this may be the culprit
|
||||
if (x % 23 == 0) {
|
||||
uint elemcborlen = elemArray[i].length - x >= 24 ? 23 : elemArray[i].length - x;
|
||||
elemcborlen += 0x40;
|
||||
uint lctr = ctr;
|
||||
while (byte(elemcborlen).length > ctr - lctr) {
|
||||
res[ctr] = byte(elemcborlen)[ctr - lctr];
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
res[ctr] = elemArray[i][x];
|
||||
ctr++;
|
||||
}
|
||||
res[ctr] = 0xFF;
|
||||
ctr++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
// </ORACLIZE_API>
|
||||
@@ -0,0 +1,71 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* DO NOT USE: under development
|
||||
*/
|
||||
|
||||
import "lib/ethereans/management/Owned.sol" ;
|
||||
|
||||
contract GitBountyBank is Owned {
|
||||
|
||||
mapping (uint => Bounty) bounties;
|
||||
uint lockPeriod = 1 month;
|
||||
struct Bounty {
|
||||
bool open;
|
||||
uint closedAt;
|
||||
uint stats;
|
||||
uint statsClaimed;
|
||||
|
||||
mapping (uint=>Account) deposits;
|
||||
uint depositIndex;
|
||||
uint deposited;
|
||||
mapping (bytes20=>Account) claims;
|
||||
uint claimed;
|
||||
|
||||
}
|
||||
|
||||
struct Account {
|
||||
address owner;
|
||||
uint amount;
|
||||
}
|
||||
|
||||
|
||||
function balanceOf(uint num) constant returns(uint){
|
||||
return bounties[num].deposited - bounties[num].claimed;
|
||||
}
|
||||
|
||||
function setState(uint num, uint stats, bool open, uint closedAt){
|
||||
if (bounties[num].stats >= stats) throw;
|
||||
bounties[num].stats = stats;
|
||||
bounties[num].open = open;
|
||||
bounties[num].closedAt = closedAt;
|
||||
}
|
||||
|
||||
function deposit(uint num, address account)
|
||||
payable returns (uint reciept) {
|
||||
if (!bounties[num].open) throw;
|
||||
reciept = bounties[num].depositIndex;
|
||||
bounties[num].deposits[reciept] = { owner: account, amount: msg.value };
|
||||
bounties[num].depositIndex++;
|
||||
bounties[num].balance += msg.value;
|
||||
return reciept;
|
||||
}
|
||||
|
||||
function withdraw(uint num, uint reciept, address account) internal {
|
||||
if (!bounties[num].open || now < bounties[num].closedAt+lockPeriod) throw;
|
||||
if(bounties[num].deposits[reciept].owner != account) throw;
|
||||
uint avaliable = bounties[num].deposits[reciept].amount;
|
||||
delete bounties[num].deposits[reciept];
|
||||
bounties[num].balance -= avaliable;
|
||||
if(!account.send(avaliable)) throw;
|
||||
}
|
||||
|
||||
function claim(uint num, uint stats, bytes20 commitid, address beneficiary) internal {
|
||||
if (bounties[num].open || now < bounties[num].closedAt+lockPeriod) throw;
|
||||
uint balance = bounties[num].deposited - bounties[num].claimed;
|
||||
uint remainingStats = bounties[num].stats - bounties[num].statsClaimed;
|
||||
bounties[num].claims[commitid] = { owner: account, amount: stats };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,21 +12,34 @@ pragma solidity ^0.4.8;
|
||||
GitHubOracle public oracle;
|
||||
//stores repository name, used for claim calls
|
||||
string private repository;
|
||||
//stores repository name in sha3, used by GitHubOracle
|
||||
bytes32 public sha3repository;
|
||||
string private uid;
|
||||
mapping (uint => Issue) issues;
|
||||
|
||||
struct Issue {
|
||||
bool state;
|
||||
uint balance;
|
||||
uint unlock;
|
||||
address claimer;
|
||||
bool claimed;
|
||||
}
|
||||
|
||||
|
||||
modifier only_oracle {
|
||||
if (msg.sender != address(oracle)) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
function GitHubIssues(string _repository, GitHubOracle _oracle) {
|
||||
function GitHubIssues(uint _uid, string _repository, GitHubOracle _oracle) {
|
||||
uid = _uid;
|
||||
oracle = _oracle;
|
||||
repository = _repository;
|
||||
sha3repository = sha3(_repository);
|
||||
}
|
||||
|
||||
function update(uint num){
|
||||
|
||||
function setState(uint num, bool open){
|
||||
issues[num] = open;
|
||||
}
|
||||
|
||||
function placeBounty(uint num){
|
||||
issues[num]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that oracle github API
|
||||
*
|
||||
* GitHubOracle register users and create GitHubToken contracts
|
||||
* Registration requires user create a gist with only their account address
|
||||
* GitHubOracle will create one GitHubToken contract per repository
|
||||
* GitHubToken mint tokens by commit only for registered users in GitHubOracle
|
||||
* GitHubToken is a LockableCoin, that accept donatations and can be withdrawn by Token Holders
|
||||
* The lookups are done by Oraclize that charge a small fee
|
||||
* The contract itself will never charge any fee
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "lib/StringLib.sol";
|
||||
import "lib/JSONLib.sol";
|
||||
|
||||
import "lib/oraclize/oraclizeAPI_0.4.sol";
|
||||
import "lib/ethereans/management/Owned.sol";
|
||||
import "./git-repository/GitRepositoryFactoryI.sol";
|
||||
import "./storage/GitHubOracleStorageI.sol";
|
||||
|
||||
|
||||
|
||||
contract GitHubOracle is Owned, usingOraclize {
|
||||
|
||||
using StringLib for string;
|
||||
|
||||
GitRepositoryFactoryI public gitRepositoryFactoryI;
|
||||
GitHubOracleStorageI public db;
|
||||
|
||||
enum OracleType { SET_REPOSITORY, SET_USER, CLAIM_COMMIT, UPDATE_ISSUE }
|
||||
mapping (bytes32 => OracleType) claimType; //temporary db enumerating oraclize calls
|
||||
mapping (bytes32 => CommitClaim) commitClaim; //temporary db for oraclize commit token claim calls
|
||||
mapping (bytes32 => UserClaim) userClaim; //temporary db for oraclize user register queries
|
||||
|
||||
string private credentials = ""; //store encrypted values of api access credentials
|
||||
string private secret = "";
|
||||
string private client = "";
|
||||
string private script = "";
|
||||
|
||||
//stores temporary data for oraclize user register request
|
||||
struct UserClaim {
|
||||
address sender;
|
||||
string githubid;
|
||||
}
|
||||
//stores temporary data for oraclize repository commit claim
|
||||
struct CommitClaim {
|
||||
string repository;
|
||||
string commitid;
|
||||
}
|
||||
|
||||
function GitHubOracle(GitHubOracleStorageI _db, GitRepositoryFactoryI _gitRepositoryFactoryI){ //
|
||||
gitRepositoryFactoryI = _gitRepositoryFactoryI;
|
||||
db = _db;
|
||||
}
|
||||
|
||||
//register or change a github user ethereum address 100000000000000000
|
||||
function register(string _github_user, string _gistid)
|
||||
payable {
|
||||
bytes32 ocid = oraclize_query("nested", StringLib.concat("[identity] ${[URL] https://gist.githubusercontent.com/",_github_user,"/",_gistid,"/raw/}, ${[URL] json(https://api.github.com/gists/").concat(_gistid,credentials,").owner.[id,login]}"));
|
||||
claimType[ocid] = OracleType.SET_USER;
|
||||
userClaim[ocid] = UserClaim({sender: msg.sender, githubid: _github_user});
|
||||
}
|
||||
|
||||
function claimCommit(string _repository, string _commitid)
|
||||
payable {
|
||||
bytes32 ocid = oraclize_query("URL", StringLib.concat("json(https://api.github.com/repos/",_repository,"/commits/", _commitid, credentials).concat(").[author,stats].[id,total]"));
|
||||
claimType[ocid] = OracleType.CLAIM_COMMIT;
|
||||
commitClaim[ocid] = CommitClaim( { repository: _repository, commitid:_commitid});
|
||||
}
|
||||
|
||||
function addRepository(string _repository)
|
||||
payable {
|
||||
bytes32 ocid = oraclize_query("URL", StringLib.concat("json(https://api.github.com/repos/",_repository,credentials,").$.id,full_name,watchers,subscribers_count"),4000000);
|
||||
claimType[ocid] = OracleType.SET_REPOSITORY;
|
||||
}
|
||||
|
||||
|
||||
function getRepository(uint id) constant returns (address){
|
||||
return db.getRepositoryAddress(projectId);
|
||||
}
|
||||
|
||||
function getRepository(string full_name) constant returns (address){
|
||||
return db.getRepositoryAddress(full_name);
|
||||
}
|
||||
|
||||
function setScript(string _script){
|
||||
script = _script;
|
||||
}
|
||||
|
||||
//owner management
|
||||
function setAPICredentials(string _client_id, string _client_secret)
|
||||
only_owner {
|
||||
credentials = StringLib.concat("?client_id=${[decrypt] ", _client_id,"}&client_secret=${[decrypt] ", _client_secret,"}");
|
||||
}
|
||||
|
||||
function clearAPICredentials()
|
||||
only_owner {
|
||||
credentials = "";
|
||||
}
|
||||
|
||||
|
||||
function bountyIssue(uint repositoryId, uint issueId) payable{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Internal Functions
|
||||
|
||||
|
||||
//
|
||||
event OracleEvent(bytes32 myid, string result, bytes proof);
|
||||
//oraclize response callback
|
||||
|
||||
function __callback(bytes32 myid, string result, bytes proof) {
|
||||
OracleEvent(myid,result,proof);
|
||||
if (msg.sender != oraclize.cbAddress()){
|
||||
throw;
|
||||
}else if(claimType[myid]==OracleType.SET_USER){
|
||||
_register(myid, result);
|
||||
}else if(claimType[myid]==OracleType.CLAIM_COMMIT){
|
||||
_claimCommit(myid, result);
|
||||
}else if(claimType[myid] == OracleType.SET_REPOSITORY){
|
||||
_setRepository(myid, result);
|
||||
}
|
||||
delete claimType[myid]; //should always be deleted
|
||||
}
|
||||
|
||||
event UserSet(string githubLogin);
|
||||
function _register(bytes32 myid, string result)
|
||||
internal {
|
||||
uint256 userId; string memory login; address addrLoaded;
|
||||
uint8 utype; //TODO
|
||||
bytes memory v = bytes(result);
|
||||
uint8 pos = 0;
|
||||
(addrLoaded,pos) = JSONLib.getNextAddr(v,pos);
|
||||
(userId,pos) = JSONLib.getNextUInt(v,pos);
|
||||
(login,pos) = JSONLib.getNextString(v,pos);
|
||||
if(userClaim[myid].sender == addrLoaded && userClaim[myid].githubid.compare(login) == 0){
|
||||
UserSet(login);
|
||||
db.addUser(userId, login, utype, addrLoaded);
|
||||
} //TODO: update user login and address;
|
||||
delete userClaim[myid]; //should always be deleted
|
||||
}
|
||||
|
||||
event GitRepositoryRegistered(uint256 projectId, string full_name, uint256 watchers, uint256 subscribers);
|
||||
function _setRepository(bytes32 myid, string result) //[83725290, "ethereans/github-token", 4, 2]
|
||||
{
|
||||
uint256 projectId; string memory full_name; uint256 watchers; uint256 subscribers;
|
||||
uint256 ownerId; string memory name; //TODO
|
||||
bytes memory v = bytes(result);
|
||||
uint8 pos = 0;
|
||||
(projectId,pos) = JSONLib.getNextUInt(v,pos);
|
||||
(full_name,pos) = JSONLib.getNextString(v,pos);
|
||||
(watchers,pos) = JSONLib.getNextUInt(v,pos);
|
||||
(subscribers,pos) = JSONLib.getNextUInt(v,pos);
|
||||
address repository = db.getRepositoryAddress(projectId);
|
||||
if(repository == 0x0){
|
||||
GitRepositoryRegistered(projectId,full_name,watchers,subscribers);
|
||||
repository = gitRepositoryFactoryI.newGitRepository(projectId,full_name);
|
||||
db.addRepository(projectId,ownerId,name,full_name,repository);
|
||||
}
|
||||
GitRepositoryI(repository).setStats(subscribers,watchers);
|
||||
}
|
||||
|
||||
event NewClaim(string repository, string commitid, uint userid, uint total );
|
||||
function _claimCommit(bytes32 myid, string result)
|
||||
internal {
|
||||
uint256 total; uint256 userId;
|
||||
bytes memory v = bytes(result);
|
||||
uint8 pos = 0;
|
||||
(userId,pos) = JSONLib.getNextUInt(v,pos);
|
||||
(total,pos) = JSONLib.getNextUInt(v,pos);
|
||||
NewClaim(commitClaim[myid].repository,commitClaim[myid].commitid,userId,total);
|
||||
GitRepositoryI repository = GitRepositoryI(db.getRepositoryAddress(commitClaim[myid].repository));
|
||||
repository.claim(commitClaim[myid].commitid.parseBytes20(), db.getUserAddress(userId), total);
|
||||
delete commitClaim[myid]; //should always be deleted
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that mint tokens by github commit stats
|
||||
*
|
||||
* GitHubOracle register users and create GitHubToken contracts
|
||||
* Registration requires user create a gist with only their account address
|
||||
* GitHubOracle will create one GitHubToken contract per repository
|
||||
* GitHubToken mint tokens by commit only for registered users in GitHubOracle
|
||||
* GitHubToken is a LockableCoin, that accept donatations and can be withdrawn by Token Holders
|
||||
* The lookups are done by Oraclize that charge a small fee
|
||||
* The contract itself will never charge any fee
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "lib/ethereans/management/Owned.sol";
|
||||
import "./GitRepositoryI.sol";
|
||||
import "./GitRepositoryToken.sol";
|
||||
import "./GitRepositoryStorage.sol";
|
||||
|
||||
contract GitRepository is GitRepositoryI, Owned {
|
||||
|
||||
//Address of the oracle, used for github login address lookup
|
||||
GitRepositoryStorage public db;
|
||||
GitRepositoryToken public token;
|
||||
|
||||
uint256 public subscribers;
|
||||
uint256 public watchers;
|
||||
//claim event
|
||||
event Claim(bytes32 commit);
|
||||
|
||||
//protect against double claiming
|
||||
modifier not_claimed(bytes20 commitid) {
|
||||
if(isClaimed(commitid)) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
function GitRepository(uint256 _uid, string _name) {
|
||||
db = new GitRepositoryStorage(_uid,_name);
|
||||
token = new GitRepositoryToken(_name);
|
||||
}
|
||||
|
||||
//checks if a commit is already claimed
|
||||
function isClaimed(bytes20 _commitid)
|
||||
constant
|
||||
returns (bool) {
|
||||
return db.commits(_commitid) != 0x0;
|
||||
}
|
||||
|
||||
//oracle claim request
|
||||
function claim(bytes20 _commitid, address _user, uint _total)
|
||||
only_owner {
|
||||
if(_total > 0 && !token.lock()){
|
||||
if(_user != 0x0 && db.commits(_commitid) != 0x0){
|
||||
Claim(_commitid);
|
||||
db.setClaimed(_commitid,_user);
|
||||
token.mint(_user, _total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setStats(uint256 _subscribers, uint256 _watchers)
|
||||
only_owner {
|
||||
subscribers = _subscribers;
|
||||
watchers = _watchers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "./GitRepository.sol";
|
||||
import "./GitRepositoryFactoryI.sol";
|
||||
|
||||
contract GitRepositoryFactory is GitRepositoryFactoryI {
|
||||
|
||||
function newGitRepository(uint256 _uid, string _name) external returns (GitRepositoryI){
|
||||
GitRepository repo = new GitRepository(_uid,_name);
|
||||
repo.setOwner(msg.sender);
|
||||
return GitRepositoryI(repo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "./GitRepositoryI.sol";
|
||||
|
||||
contract GitRepositoryFactoryI {
|
||||
function newGitRepository(uint256 _uid, string _name) external returns (GitRepositoryI);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
contract GitRepositoryI {
|
||||
function isClaimed(bytes20 _commitid) constant returns (bool);
|
||||
function claim(bytes20 _commitid, address _user, uint _total);
|
||||
function setStats(uint256 _subscribers, uint256 _watchers);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that oracle github API
|
||||
*
|
||||
* GitHubRegistry is a storage contract
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
import "lib/ethereans/management/Owned.sol";
|
||||
|
||||
contract GitRepositoryStorage is Owned {
|
||||
|
||||
string public name;
|
||||
uint256 public uid;
|
||||
|
||||
//storage of sha3(login) of github users
|
||||
mapping (bytes32 => address) users;
|
||||
|
||||
mapping (bytes20 => address) public commits;
|
||||
|
||||
function setClaimed(bytes20 _commitid, address _claimer)
|
||||
only_owner {
|
||||
commits[_commitid] = _claimer;
|
||||
}
|
||||
|
||||
function setUser(bytes32 _user, address _account)
|
||||
only_owner {
|
||||
users[_user] = _account;
|
||||
if(_account == 0x0){
|
||||
delete users[_user];
|
||||
}
|
||||
}
|
||||
|
||||
function GitRepositoryStorage(uint256 _uid, string _name){
|
||||
uid = _uid;
|
||||
name = _name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that mint tokens by github commit stats
|
||||
*
|
||||
* GitHubOracle register users and create GitHubToken contracts
|
||||
* Registration requires user create a gist with only their account address
|
||||
* GitHubOracle will create one GitHubToken contract per repository
|
||||
* GitHubToken mint tokens by commit only for registered users in GitHubOracle
|
||||
* GitHubToken is a LockableCoin, that accept donatations and can be withdrawn by Token Holders
|
||||
* The lookups are done by Oraclize that charge a small fee
|
||||
* The contract itself will never charge any fee
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "lib/ethereans/token/CollaborationToken.sol";
|
||||
import "lib/ethereans/management/Owned.sol";
|
||||
|
||||
contract GitRepositoryToken is CollaborationToken, Owned {
|
||||
|
||||
function GitRepositoryToken(string _repository) {
|
||||
setAttribute("name", _repository);
|
||||
setAttribute("symbol", "GIT");
|
||||
setDecimalBase(0);
|
||||
}
|
||||
|
||||
function mint(address _who, uint256 _value)
|
||||
only_owner {
|
||||
_mint(_who,_value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that oracle github API
|
||||
*
|
||||
* GitHubRegistry is a storage contract
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
import "lib/ethereans/management/Owned.sol";
|
||||
import "./GitHubOracleStorageI.sol";
|
||||
contract GitHubOracleStorage is GitHubOracleStorageI, Owned {
|
||||
|
||||
mapping (string => uint256) repositoryNames;
|
||||
mapping (string => uint256) userNames;
|
||||
mapping (uint256 => Repository) repositories;
|
||||
mapping (uint256 => User) users;
|
||||
|
||||
struct Repository {
|
||||
uint256 owner;
|
||||
string name;
|
||||
string full_name;
|
||||
address addr;
|
||||
uint256 claimed;
|
||||
}
|
||||
|
||||
struct User {
|
||||
string login;
|
||||
uint8 utype;
|
||||
address addr;
|
||||
uint256 claimed;
|
||||
}
|
||||
|
||||
|
||||
function addRepository(uint256 _id, uint256 _owner, string _name, string _full_name, address _addr) only_owner {
|
||||
repositories[_id] = Repository({owner:_owner,name:_name,full_name:_full_name,addr:_addr,claimed:0});
|
||||
repositoryNames[_full_name] = _id;
|
||||
}
|
||||
|
||||
function addUser(uint256 _id, string _login, uint8 _utype, address _addr) only_owner{
|
||||
users[_id] = User({login:_login,utype:_utype,addr:_addr, claimed:0});
|
||||
userNames[_login] = _id;
|
||||
}
|
||||
|
||||
function setRepositoryAddress(uint256 _repositoryId, address _repositoryAddress)
|
||||
only_owner {
|
||||
repositories[_repositoryId].addr = _repositoryAddress;
|
||||
}
|
||||
|
||||
function setUserAddress(uint userId, address account)
|
||||
only_owner{
|
||||
users[userId].addr = account;
|
||||
}
|
||||
function setRepositoryName(uint256 _repositoryId, string _full_name, string _name)
|
||||
only_owner {
|
||||
delete repositoryNames[repositories[_repositoryId].full_name];
|
||||
repositoryNames[_full_name] = _repositoryId;
|
||||
repositories[_repositoryId].full_name = _full_name;
|
||||
repositories[_repositoryId].name = _full_name;
|
||||
}
|
||||
|
||||
function setUserName(uint256 _userId, string _name)
|
||||
only_owner {
|
||||
delete userNames[users[_userId].login];
|
||||
userNames[_name] = _userId;
|
||||
users[_userId].login = _name;
|
||||
}
|
||||
|
||||
|
||||
function getUserAddress(uint256 _id) constant returns(address){
|
||||
return users[_id].addr;
|
||||
}
|
||||
function getUserAddress(string _login) constant returns(address){
|
||||
return users[userNames[_login]].addr;
|
||||
}
|
||||
function getRepositoryAddress(uint256 _id) constant returns(address){
|
||||
return repositories[_id].addr;
|
||||
}
|
||||
function getRepositoryAddress(string _full_name) constant returns(address){
|
||||
return repositories[repositoryNames[_full_name]].addr;
|
||||
}
|
||||
function getRepositoryId(string _full_name) constant returns (uint256){
|
||||
return repositoryNames[_full_name];
|
||||
}
|
||||
function getRepositoryName(uint256 _id) constant returns (string){
|
||||
return repositories[_id].full_name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
/**
|
||||
* Contract that oracle github API
|
||||
*
|
||||
* GitHubRegistry is a storage contract
|
||||
*
|
||||
* By Ricardo Guilherme Schmidt
|
||||
* Released under GPLv3 License
|
||||
*/
|
||||
|
||||
contract GitHubOracleStorageI {
|
||||
|
||||
function addRepository(uint256 _id, uint256 _owner, string _name, string _full_name, address _addr);
|
||||
function addUser(uint256 _id, string _login, uint8 _type, address _addr);
|
||||
function setRepositoryAddress(uint256 _repositoryId, address _repositoryAddress);
|
||||
function setRepositoryName(uint256 _repositoryId, string _full_name, string _name);
|
||||
function setUserAddress(uint userId, address account);
|
||||
function setUserName(uint256 _userId, string _name);
|
||||
function getRepositoryId(string _full_name) constant returns (uint256);
|
||||
function getRepositoryName(uint256 _id) constant returns (string);
|
||||
function getRepositoryAddress(uint256 _id) constant returns(address);
|
||||
function getRepositoryAddress(string _full_name) constant returns(address);
|
||||
function getUserAddress(uint256 _id) constant returns(address);
|
||||
function getUserAddress(string _login) constant returns(address);
|
||||
|
||||
}
|
||||
+8
-6
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"contracts": "contracts",
|
||||
|
||||
"deploy": ["GitHubOracle"],
|
||||
"deploy": ["GitHubOracleStorage", "GitRepositoryFactory", "GitHubOracle"],
|
||||
|
||||
"plugins": {
|
||||
"oraclize": {
|
||||
"networkID": 161,
|
||||
@@ -13,22 +14,23 @@
|
||||
"block": {
|
||||
"coinbase" : "0xdedb49385ad5b94a16f236a6890cf9e0b1e30392",
|
||||
"difficulty" : "0x0100",
|
||||
"gasLimit" : 8141592,
|
||||
"gasPrice": 60000000000
|
||||
"gasLimit" : 6061924 ,
|
||||
"gasPrice": 40000000000
|
||||
},
|
||||
"accounts": {
|
||||
"0xdedb49385ad5b94a16f236a6890cf9e0b1e30392": {
|
||||
"balance": 1000000000000000000000000000000000000000000000000000000 ,
|
||||
"balance": 100000000000000000000000000000000000000000000000000000000000000 ,
|
||||
"nonce": "0x1cf",
|
||||
"pkey": "0x974f963ee4571e86e5f9bc3b493e453db9c15e5bd19829a4ef9a790de0da0015",
|
||||
"default": false
|
||||
"default": true
|
||||
},
|
||||
"0x1081108d14493ead0d4071cc757688ed7b111c32": {
|
||||
"balance": 1000000000000000000000000000000000000000000000000000000 ,
|
||||
"nonce": "0x1cf",
|
||||
"pkey": "0x6321991cf5102acf1efd6085da03b398a56cdc887b38acb1ba1452a50bc79343",
|
||||
"default": true
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Not working due sandbox limitation
|
||||
|
||||
# Call method claim(string)
|
||||
- from: '0x1081108d14493ead0d4071cc757688ed7b111c32'
|
||||
to: '0x77a0e95b5d58cdb9b54f75e33b8764c87496abd1'
|
||||
value: '0x16345785d8a0000'
|
||||
call: claim(string)
|
||||
args:
|
||||
- e0a340e72784b1322929d6803773b31a2b6b5707
|
||||
#transfer 101 eth
|
||||
- from: '0x1081108d14493ead0d4071cc757688ed7b111c32'
|
||||
to: '0x77a0e95b5d58cdb9b54f75e33b8764c87496abd1'
|
||||
value: '0x579a814e10a740000'
|
||||
data: null
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
#
|
||||
# Scenario3
|
||||
#
|
||||
# Created on: 20/03/2017 02:44:46
|
||||
#
|
||||
|
||||
# Create contract GitRepositoryFactory
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: null
|
||||
value: '0x0'
|
||||
contract:
|
||||
name: GitRepositoryFactory
|
||||
dir: contracts/
|
||||
sources:
|
||||
- lib/ethereans/bank/Bank.sol
|
||||
- lib/ethereans/management/Owned.sol
|
||||
- lib/ethereans/management/Secret.sol
|
||||
- lib/ethereans/token/AbstractToken.sol
|
||||
- lib/ethereans/token/CollaborationToken.sol
|
||||
- lib/ethereans/token/JustifiedCollaborationToken.sol
|
||||
- lib/ethereans/token/Token.sol
|
||||
- lib/ethereans/token/WrappedEthToken.sol
|
||||
- lib/ethereans/util/Bytes32Lib.sol
|
||||
- lib/ethereans/util/IntLib.sol
|
||||
- lib/JSONLib.sol
|
||||
- lib/StringLib.sol
|
||||
- lib/oraclize/oraclizeAPI_0.4.sol
|
||||
- src/AbstractBounty.sol
|
||||
- src/GitHubIssues.sol
|
||||
- src/GitHubOracle.sol
|
||||
- src/git-repository/GitRepository.sol
|
||||
- src/git-repository/GitRepositoryFactory.sol
|
||||
- src/git-repository/GitRepositoryFactoryI.sol
|
||||
- src/git-repository/GitRepositoryI.sol
|
||||
- src/git-repository/GitRepositoryStorage.sol
|
||||
- src/git-repository/GitRepositoryToken.sol
|
||||
- src/storage/GitHubOracleStorage.sol
|
||||
- src/storage/GitHubOracleStorageI.sol
|
||||
args: []
|
||||
|
||||
# Create contract GitHubOracleStorage
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: null
|
||||
value: '0x0'
|
||||
contract:
|
||||
name: GitHubOracleStorage
|
||||
dir: contracts/
|
||||
sources:
|
||||
- lib/ethereans/bank/Bank.sol
|
||||
- lib/ethereans/management/Owned.sol
|
||||
- lib/ethereans/management/Secret.sol
|
||||
- lib/ethereans/token/AbstractToken.sol
|
||||
- lib/ethereans/token/CollaborationToken.sol
|
||||
- lib/ethereans/token/JustifiedCollaborationToken.sol
|
||||
- lib/ethereans/token/Token.sol
|
||||
- lib/ethereans/token/WrappedEthToken.sol
|
||||
- lib/ethereans/util/Bytes32Lib.sol
|
||||
- lib/ethereans/util/IntLib.sol
|
||||
- lib/JSONLib.sol
|
||||
- lib/StringLib.sol
|
||||
- lib/oraclize/oraclizeAPI_0.4.sol
|
||||
- src/AbstractBounty.sol
|
||||
- src/GitHubIssues.sol
|
||||
- src/GitHubOracle.sol
|
||||
- src/git-repository/GitRepository.sol
|
||||
- src/git-repository/GitRepositoryFactory.sol
|
||||
- src/git-repository/GitRepositoryFactoryI.sol
|
||||
- src/git-repository/GitRepositoryI.sol
|
||||
- src/git-repository/GitRepositoryStorage.sol
|
||||
- src/git-repository/GitRepositoryToken.sol
|
||||
- src/storage/GitHubOracleStorage.sol
|
||||
- src/storage/GitHubOracleStorageI.sol
|
||||
args: []
|
||||
|
||||
# Create contract GitHubOracle
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: null
|
||||
value: '0x0'
|
||||
contract:
|
||||
name: GitHubOracle
|
||||
dir: contracts/
|
||||
sources:
|
||||
- lib/ethereans/bank/Bank.sol
|
||||
- lib/ethereans/management/Owned.sol
|
||||
- lib/ethereans/management/Secret.sol
|
||||
- lib/ethereans/token/AbstractToken.sol
|
||||
- lib/ethereans/token/CollaborationToken.sol
|
||||
- lib/ethereans/token/JustifiedCollaborationToken.sol
|
||||
- lib/ethereans/token/Token.sol
|
||||
- lib/ethereans/token/WrappedEthToken.sol
|
||||
- lib/ethereans/util/Bytes32Lib.sol
|
||||
- lib/ethereans/util/IntLib.sol
|
||||
- lib/JSONLib.sol
|
||||
- lib/StringLib.sol
|
||||
- lib/oraclize/oraclizeAPI_0.4.sol
|
||||
- src/AbstractBounty.sol
|
||||
- src/GitHubIssues.sol
|
||||
- src/GitHubOracle.sol
|
||||
- src/git-repository/GitRepository.sol
|
||||
- src/git-repository/GitRepositoryFactory.sol
|
||||
- src/git-repository/GitRepositoryFactoryI.sol
|
||||
- src/git-repository/GitRepositoryI.sol
|
||||
- src/git-repository/GitRepositoryStorage.sol
|
||||
- src/git-repository/GitRepositoryToken.sol
|
||||
- src/storage/GitHubOracleStorage.sol
|
||||
- src/storage/GitHubOracleStorageI.sol
|
||||
args:
|
||||
- '0xdf315f7485c3a86eb692487588735f224482abe3'
|
||||
- '0x17956ba5f4291844bc25aedb27e69bc11b5bda39'
|
||||
|
||||
# Call method setOwner(address)
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: '0xdf315f7485c3a86eb692487588735f224482abe3'
|
||||
value: '0x0'
|
||||
call: setOwner(address)
|
||||
args:
|
||||
- '0x06b179aabf198ced0f98c8ceca905a920a137ef4'
|
||||
|
||||
# Call method addRepository(string)
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: '0x06b179aabf198ced0f98c8ceca905a920a137ef4'
|
||||
value: '0x16345785d8a0000'
|
||||
call: addRepository(string)
|
||||
args:
|
||||
- ethereans/github-token
|
||||
|
||||
# Call method register(string,string)
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: '0x06b179aabf198ced0f98c8ceca905a920a137ef4'
|
||||
value: '0x38D7EA4C68000'
|
||||
call: 'register(string,string)'
|
||||
args:
|
||||
- 3esmit
|
||||
- 31a58f2ddf2258697cce1b969e7c298b
|
||||
|
||||
# Call method claimCommit(string,string)
|
||||
- from: '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
to: '0x06b179aabf198ced0f98c8ceca905a920a137ef4'
|
||||
value: '0x2386f26fc10000'
|
||||
call: 'claimCommit(string,string)'
|
||||
args:
|
||||
- ethereans/github-token
|
||||
- 09ba429f22eec6cefcfa7a862f60b9d4cc1cfa14
|
||||
@@ -1,25 +0,0 @@
|
||||
#
|
||||
# Create, register user, register repository and claim commits
|
||||
#
|
||||
# Created on: 01/03/2017 12:02:15
|
||||
#
|
||||
|
||||
|
||||
# Call method addRepository(string)
|
||||
- from: '0x1081108d14493ead0d4071cc757688ed7b111c32'
|
||||
to: '0x838ef69e5948e423db15757059d538b5bcaf659e'
|
||||
value: '0x0'
|
||||
call: addRepository(string)
|
||||
args:
|
||||
- ethereans/github-token
|
||||
|
||||
# Call method register(string,string)
|
||||
- from: '0x1081108d14493ead0d4071cc757688ed7b111c32'
|
||||
to: '0x838ef69e5948e423db15757059d538b5bcaf659e'
|
||||
value: '0x16345785d8a0000'
|
||||
call: 'register(string,string)'
|
||||
args:
|
||||
- 3esmit
|
||||
- 31a58f2ddf2258697cce1b969e7c298b
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# Scenario1
|
||||
#
|
||||
# Created on: 06/03/2017 09:44:46
|
||||
#
|
||||
|
||||
# Call method setAPICredentials(string,string)
|
||||
- from: '0x1081108d14493ead0d4071cc757688ed7b111c32'
|
||||
to: '0x838ef69e5948e423db15757059d538b5bcaf659e'
|
||||
value: '0x0'
|
||||
call: 'setAPICredentials(string,string)'
|
||||
args:
|
||||
- BLX/GHYsFjUNDKfRXSmJAGDrwzO3p1XFpK2DG9nwRHJ0wHMTA7K4wMj+eoKWc6HpkXnxwn/mC8GPsz3bbPnM6luWa7qLHdT94bQX4g19icuzgfm/4BkY6oK/EUhoE8IU34frpF4=
|
||||
- BEMxXob2oNvdvo44KXhyBgou2xqr0Lits2wCy/OzrAIsfg5HO+GOEhdcEYrEByjhQosAJJX7uvuj7GVH65J8X7IFUFLrvWabWdTmPIEXwXoBGeU67z6SUtzOOgvAvFKixfl8pAWCDacJGZVQOoY+97tq140VAACEOA==
|
||||
@@ -1,16 +0,0 @@
|
||||
#
|
||||
# Scenario1
|
||||
#
|
||||
# Created on: 01/03/2017 17:55:37
|
||||
#
|
||||
|
||||
|
||||
# Call method transfer(address,uint256)
|
||||
- from: '0x1081108d14493ead0d4071cc757688ed7b111c32'
|
||||
to: '0x77a0e95b5d58cdb9b54f75e33b8764c87496abd1'
|
||||
value: '0x0'
|
||||
call: 'transfer(address,uint256)'
|
||||
args:
|
||||
- '0xdedb49385ad5b94a16f236a6890cf9e0b1e30392'
|
||||
- 440
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import sys
|
||||
import json
|
||||
import urllib
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
auth = "?client_id=&client_secret="
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
FROM ubuntu:14.04
|
||||
RUN apt-get update && apt-get install -y python
|
||||
ADD testarg.py testarg.py
|
||||
MAINTAINER Ricardo “3esmit@gmail.com”
|
||||
CMD python testarg.py
|
||||
@@ -0,0 +1 @@
|
||||
# TheEtherian
|
||||
@@ -0,0 +1,112 @@
|
||||
import os, argparse
|
||||
import json, urllib2, datetime
|
||||
from collections import defaultdict
|
||||
start = ''
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--client')
|
||||
parser.add_argument('--secret')
|
||||
parser.add_argument('--script')
|
||||
parser.add_argument('--username')
|
||||
parser.add_argument('--userid')
|
||||
parser.add_argument('--repoid')
|
||||
parser.add_argument('--reponame')
|
||||
parser.add_argument('--issueid')
|
||||
parser.add_argument('--pullid')
|
||||
parser.add_argument('--commit')
|
||||
|
||||
|
||||
argn = []
|
||||
try:
|
||||
for x in range(0, int(os.environ['ARGN'])):
|
||||
argn[x] = os.environ['ARG'+`x`]
|
||||
args = parser.parse_args(argn);
|
||||
except KeyError:
|
||||
args = parser.parse_args()
|
||||
|
||||
if(args.client is not None and args.secret is not None):
|
||||
client_id = args.client
|
||||
client_secret = args.secret
|
||||
auth = "?client_id="+client_id+"&client_secret="+client_secret
|
||||
else:
|
||||
auth = ""
|
||||
|
||||
repo_link = ""
|
||||
if(args.reponame is not None):
|
||||
repo_link = "https://api.github.com/repos/" + args.reponame
|
||||
else:
|
||||
repo_link = "https://api.github.com/repositories/" + args.repoid
|
||||
|
||||
|
||||
|
||||
|
||||
def relatedIssues(issue):
|
||||
link_issue = repo_link + "/issues/" + issue + "/timeline" + auth
|
||||
print link_issue
|
||||
req = urllib2.Request(link_issue)
|
||||
req.add_header("Accept", "application/vnd.github.mockingbird-preview")
|
||||
issue = json.load(urllib2.urlopen(req))
|
||||
for elem in issue:
|
||||
if(elem["event"] == "cross-referenced"):
|
||||
if(elem["source"]["type"] == "issue"):
|
||||
#print elem["source"]["issue"]["number"];
|
||||
pullCommitPoints(json.dumps(elem["source"]["issue"]["number"]))
|
||||
|
||||
|
||||
|
||||
def issueStatus(issue):
|
||||
link_issue = repo_link + "/issues/" + issue + auth
|
||||
issue = json.load(urllib2.urlopen(link_issue))
|
||||
if(issue['state'] == "closed"):
|
||||
print datetime.datetime.strptime( json.dumps(issue['closed_at'])[1:-1], "%Y-%m-%dT%H:%M:%SZ" ).strftime('%s') +","+ json.dumps(issue['closed_by']['login'])
|
||||
else:
|
||||
print "open"
|
||||
|
||||
|
||||
def pullCommitPoints(pr):
|
||||
link_pull = repo_link + "/pulls/" + pr + auth
|
||||
pull = json.load(urllib2.urlopen(link_pull))
|
||||
if(pull['merged_at']):
|
||||
link_pulls_commits = repo_link + "/pulls/" + pr + "/commits" +auth
|
||||
points = defaultdict(int)
|
||||
commits = json.load(urllib2.urlopen(link_pulls_commits))
|
||||
for commit in commits:
|
||||
if(commit['url']):
|
||||
link_commit = json.dumps(commit['url'])[1:-1] +auth
|
||||
_commit = json.load(urllib2.urlopen(link_commit))
|
||||
author = json.dumps(_commit['author']['login'])[1:-1]
|
||||
points[author] += int(json.dumps(_commit['stats']['total']))
|
||||
print points.items()
|
||||
|
||||
|
||||
def issueCommits(args.issueid):
|
||||
link_issue = repo_link + "/issues/" + issue + "/timeline" + auth
|
||||
req = urllib2.Request(link_issue)
|
||||
req.add_header("Accept", "application/vnd.github.mockingbird-preview")
|
||||
issue = json.load(urllib2.urlopen(req))
|
||||
for elem in issue:
|
||||
if(elem["event"] == "cross-referenced"):
|
||||
if(elem["source"]["type"] == "issue"):
|
||||
#print elem["source"]["issue"]["number"];
|
||||
pullCommitPoints(json.dumps(elem["source"]["issue"]["number"]))
|
||||
|
||||
def commitData(commit):
|
||||
link_commit = repo_link +"/commits/"+ commit;
|
||||
req = urllib2.Request(link_commit)
|
||||
req.add_header("Accept", "application/vnd.github.mockingbird-preview")
|
||||
commit = json.load(urllib2.urlopen(req))
|
||||
print json.dumps(commit)
|
||||
|
||||
if args.script == 'issue-status':
|
||||
issueStatus(args.issueid)
|
||||
elif args.script == 'issue-commits':
|
||||
issueCommits(args.issueid)
|
||||
elif args.script == 'related-issues':
|
||||
relatedIssues(args.issueid)
|
||||
elif args.script == 'commit-points':
|
||||
pullCommitPoints(args.pullid)
|
||||
elif args.script == 'commit-data':
|
||||
commitData(args.commit)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user