Merge pull request #8 from status-im/registries

Registries defined
This commit is contained in:
Ricardo Guilherme Schmidt
2017-05-19 19:52:21 -03:00
committed by GitHub
14 changed files with 1980 additions and 529 deletions
+711
View File
@@ -0,0 +1,711 @@
/*
* @title String & slice utility library for Solidity contracts.
* @author Nick Johnson <arachnid@notdot.net>
*
* @dev Functionality in this library is largely implemented using an
* abstraction called a 'slice'. A slice represents a part of a string -
* anything from the entire string to a single character, or even no
* characters at all (a 0-length slice). Since a slice only has to specify
* an offset and a length, copying and manipulating slices is a lot less
* expensive than copying and manipulating the strings they reference.
*
* To further reduce gas costs, most functions on slice that need to return
* a slice modify the original one instead of allocating a new one; for
* instance, `s.split(".")` will return the text up to the first '.',
* modifying s to only contain the remainder of the string after the '.'.
* In situations where you do not want to modify the original slice, you
* can make a copy first with `.copy()`, for example:
* `s.copy().split(".")`. Try and avoid using this idiom in loops; since
* Solidity has no memory management, it will result in allocating many
* short-lived slices that are later discarded.
*
* Functions that return two slices come in two versions: a non-allocating
* version that takes the second slice as an argument, modifying it in
* place, and an allocating version that allocates and returns the second
* slice; see `nextRune` for example.
*
* Functions that have to copy string data will return strings rather than
* slices; these can be cast back to slices for further processing if
* required.
*
* For convenience, some functions are provided with non-modifying
* variants that create a new slice and return both; for instance,
* `s.splitNew('.')` leaves s unmodified, and returns two values
* corresponding to the left and right parts of the string.
*/
pragma solidity ^0.4.11;
library strings {
struct slice {
uint _len;
uint _ptr;
}
function memcpy(uint dest, uint src, uint len) private {
// Copy word-length chunks while possible
for(; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
// Copy remaining bytes
uint mask = 256 ** (32 - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
/*
* @dev Returns a slice containing the entire string.
* @param self The string to make a slice from.
* @return A newly allocated slice containing the entire string.
*/
function toSlice(string self) internal returns (slice) {
uint ptr;
assembly {
ptr := add(self, 0x20)
}
return slice(bytes(self).length, ptr);
}
/*
* @dev Returns the length of a null-terminated bytes32 string.
* @param self The value to find the length of.
* @return The length of the string, from 0 to 32.
*/
function len(bytes32 self) internal returns (uint) {
uint ret;
if (self == 0)
return 0;
if (self & 0xffffffffffffffffffffffffffffffff == 0) {
ret += 16;
self = bytes32(uint(self) / 0x100000000000000000000000000000000);
}
if (self & 0xffffffffffffffff == 0) {
ret += 8;
self = bytes32(uint(self) / 0x10000000000000000);
}
if (self & 0xffffffff == 0) {
ret += 4;
self = bytes32(uint(self) / 0x100000000);
}
if (self & 0xffff == 0) {
ret += 2;
self = bytes32(uint(self) / 0x10000);
}
if (self & 0xff == 0) {
ret += 1;
}
return 32 - ret;
}
/*
* @dev Returns a slice containing the entire bytes32, interpreted as a
* null-termintaed utf-8 string.
* @param self The bytes32 value to convert to a slice.
* @return A new slice containing the value of the input argument up to the
* first null.
*/
function toSliceB32(bytes32 self) internal returns (slice ret) {
// Allocate space for `self` in memory, copy it there, and point ret at it
assembly {
let ptr := mload(0x40)
mstore(0x40, add(ptr, 0x20))
mstore(ptr, self)
mstore(add(ret, 0x20), ptr)
}
ret._len = len(self);
}
/*
* @dev Returns a new slice containing the same data as the current slice.
* @param self The slice to copy.
* @return A new slice containing the same data as `self`.
*/
function copy(slice self) internal returns (slice) {
return slice(self._len, self._ptr);
}
/*
* @dev Copies a slice to a new string.
* @param self The slice to copy.
* @return A newly allocated string containing the slice's text.
*/
function toString(slice self) internal returns (string) {
var ret = new string(self._len);
uint retptr;
assembly { retptr := add(ret, 32) }
memcpy(retptr, self._ptr, self._len);
return ret;
}
/*
* @dev Returns the length in runes of the slice. Note that this operation
* takes time proportional to the length of the slice; avoid using it
* in loops, and call `slice.empty()` if you only need to know whether
* the slice is empty or not.
* @param self The slice to operate on.
* @return The length of the slice in runes.
*/
function len(slice self) internal returns (uint) {
// Starting at ptr-31 means the LSB will be the byte we care about
var ptr = self._ptr - 31;
var end = ptr + self._len;
for (uint len = 0; ptr < end; len++) {
uint8 b;
assembly { b := and(mload(ptr), 0xFF) }
if (b < 0x80) {
ptr += 1;
} else if(b < 0xE0) {
ptr += 2;
} else if(b < 0xF0) {
ptr += 3;
} else if(b < 0xF8) {
ptr += 4;
} else if(b < 0xFC) {
ptr += 5;
} else {
ptr += 6;
}
}
return len;
}
/*
* @dev Returns true if the slice is empty (has a length of 0).
* @param self The slice to operate on.
* @return True if the slice is empty, False otherwise.
*/
function empty(slice self) internal returns (bool) {
return self._len == 0;
}
/*
* @dev Returns a positive number if `other` comes lexicographically after
* `self`, a negative number if it comes before, or zero if the
* contents of the two slices are equal. Comparison is done per-rune,
* on unicode codepoints.
* @param self The first slice to compare.
* @param other The second slice to compare.
* @return The result of the comparison.
*/
function compare(slice self, slice other) internal returns (int) {
uint shortest = self._len;
if (other._len < self._len)
shortest = other._len;
var selfptr = self._ptr;
var otherptr = other._ptr;
for (uint idx = 0; idx < shortest; idx += 32) {
uint a;
uint b;
assembly {
a := mload(selfptr)
b := mload(otherptr)
}
if (a != b) {
// Mask out irrelevant bytes and check again
uint mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
var diff = (a & mask) - (b & mask);
if (diff != 0)
return int(diff);
}
selfptr += 32;
otherptr += 32;
}
return int(self._len) - int(other._len);
}
/*
* @dev Returns true if the two slices contain the same text.
* @param self The first slice to compare.
* @param self The second slice to compare.
* @return True if the slices are equal, false otherwise.
*/
function equals(slice self, slice other) internal returns (bool) {
return compare(self, other) == 0;
}
/*
* @dev Extracts the first rune in the slice into `rune`, advancing the
* slice to point to the next rune and returning `self`.
* @param self The slice to operate on.
* @param rune The slice that will contain the first rune.
* @return `rune`.
*/
function nextRune(slice self, slice rune) internal returns (slice) {
rune._ptr = self._ptr;
if (self._len == 0) {
rune._len = 0;
return rune;
}
uint len;
uint b;
// Load the first byte of the rune into the LSBs of b
assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }
if (b < 0x80) {
len = 1;
} else if(b < 0xE0) {
len = 2;
} else if(b < 0xF0) {
len = 3;
} else {
len = 4;
}
// Check for truncated codepoints
if (len > self._len) {
rune._len = self._len;
self._ptr += self._len;
self._len = 0;
return rune;
}
self._ptr += len;
self._len -= len;
rune._len = len;
return rune;
}
/*
* @dev Returns the first rune in the slice, advancing the slice to point
* to the next rune.
* @param self The slice to operate on.
* @return A slice containing only the first rune from `self`.
*/
function nextRune(slice self) internal returns (slice ret) {
nextRune(self, ret);
}
/*
* @dev Returns the number of the first codepoint in the slice.
* @param self The slice to operate on.
* @return The number of the first codepoint in the slice.
*/
function ord(slice self) internal returns (uint ret) {
if (self._len == 0) {
return 0;
}
uint word;
uint len;
uint div = 2 ** 248;
// Load the rune into the MSBs of b
assembly { word:= mload(mload(add(self, 32))) }
var b = word / div;
if (b < 0x80) {
ret = b;
len = 1;
} else if(b < 0xE0) {
ret = b & 0x1F;
len = 2;
} else if(b < 0xF0) {
ret = b & 0x0F;
len = 3;
} else {
ret = b & 0x07;
len = 4;
}
// Check for truncated codepoints
if (len > self._len) {
return 0;
}
for (uint i = 1; i < len; i++) {
div = div / 256;
b = (word / div) & 0xFF;
if (b & 0xC0 != 0x80) {
// Invalid UTF-8 sequence
return 0;
}
ret = (ret * 64) | (b & 0x3F);
}
return ret;
}
/*
* @dev Returns the keccak-256 hash of the slice.
* @param self The slice to hash.
* @return The hash of the slice.
*/
function keccak(slice self) internal returns (bytes32 ret) {
assembly {
ret := sha3(mload(add(self, 32)), mload(self))
}
}
/*
* @dev Returns true if `self` starts with `needle`.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return True if the slice starts with the provided text, false otherwise.
*/
function startsWith(slice self, slice needle) internal returns (bool) {
if (self._len < needle._len) {
return false;
}
if (self._ptr == needle._ptr) {
return true;
}
bool equal;
assembly {
let len := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
equal := eq(sha3(selfptr, len), sha3(needleptr, len))
}
return equal;
}
/*
* @dev If `self` starts with `needle`, `needle` is removed from the
* beginning of `self`. Otherwise, `self` is unmodified.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return `self`
*/
function beyond(slice self, slice needle) internal returns (slice) {
if (self._len < needle._len) {
return self;
}
bool equal = true;
if (self._ptr != needle._ptr) {
assembly {
let len := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
equal := eq(sha3(selfptr, len), sha3(needleptr, len))
}
}
if (equal) {
self._len -= needle._len;
self._ptr += needle._len;
}
return self;
}
/*
* @dev Returns true if the slice ends with `needle`.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return True if the slice starts with the provided text, false otherwise.
*/
function endsWith(slice self, slice needle) internal returns (bool) {
if (self._len < needle._len) {
return false;
}
var selfptr = self._ptr + self._len - needle._len;
if (selfptr == needle._ptr) {
return true;
}
bool equal;
assembly {
let len := mload(needle)
let needleptr := mload(add(needle, 0x20))
equal := eq(sha3(selfptr, len), sha3(needleptr, len))
}
return equal;
}
/*
* @dev If `self` ends with `needle`, `needle` is removed from the
* end of `self`. Otherwise, `self` is unmodified.
* @param self The slice to operate on.
* @param needle The slice to search for.
* @return `self`
*/
function until(slice self, slice needle) internal returns (slice) {
if (self._len < needle._len) {
return self;
}
var selfptr = self._ptr + self._len - needle._len;
bool equal = true;
if (selfptr != needle._ptr) {
assembly {
let len := mload(needle)
let needleptr := mload(add(needle, 0x20))
equal := eq(sha3(selfptr, len), sha3(needleptr, len))
}
}
if (equal) {
self._len -= needle._len;
}
return self;
}
// Returns the memory address of the first byte of the first occurrence of
// `needle` in `self`, or the first byte after `self` if not found.
function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private returns (uint) {
uint ptr;
uint idx;
if (needlelen <= selflen) {
if (needlelen <= 32) {
// Optimized assembly for 68 gas per byte on short strings
assembly {
let mask := not(sub(exp(2, mul(8, sub(32, needlelen))), 1))
let needledata := and(mload(needleptr), mask)
let end := add(selfptr, sub(selflen, needlelen))
ptr := selfptr
loop:
jumpi(exit, eq(and(mload(ptr), mask), needledata))
ptr := add(ptr, 1)
jumpi(loop, lt(sub(ptr, 1), end))
ptr := add(selfptr, selflen)
exit:
}
return ptr;
} else {
// For long needles, use hashing
bytes32 hash;
assembly { hash := sha3(needleptr, needlelen) }
ptr = selfptr;
for (idx = 0; idx <= selflen - needlelen; idx++) {
bytes32 testHash;
assembly { testHash := sha3(ptr, needlelen) }
if (hash == testHash)
return ptr;
ptr += 1;
}
}
}
return selfptr + selflen;
}
// Returns the memory address of the first byte after the last occurrence of
// `needle` in `self`, or the address of `self` if not found.
function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private returns (uint) {
uint ptr;
if (needlelen <= selflen) {
if (needlelen <= 32) {
// Optimized assembly for 69 gas per byte on short strings
assembly {
let mask := not(sub(exp(2, mul(8, sub(32, needlelen))), 1))
let needledata := and(mload(needleptr), mask)
ptr := add(selfptr, sub(selflen, needlelen))
loop:
jumpi(ret, eq(and(mload(ptr), mask), needledata))
ptr := sub(ptr, 1)
jumpi(loop, gt(add(ptr, 1), selfptr))
ptr := selfptr
jump(exit)
ret:
ptr := add(ptr, needlelen)
exit:
}
return ptr;
} else {
// For long needles, use hashing
bytes32 hash;
assembly { hash := sha3(needleptr, needlelen) }
ptr = selfptr + (selflen - needlelen);
while (ptr >= selfptr) {
bytes32 testHash;
assembly { testHash := sha3(ptr, needlelen) }
if (hash == testHash)
return ptr + needlelen;
ptr -= 1;
}
}
}
return selfptr;
}
/*
* @dev Modifies `self` to contain everything from the first occurrence of
* `needle` to the end of the slice. `self` is set to the empty slice
* if `needle` is not found.
* @param self The slice to search and modify.
* @param needle The text to search for.
* @return `self`.
*/
function find(slice self, slice needle) internal returns (slice) {
uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
self._len -= ptr - self._ptr;
self._ptr = ptr;
return self;
}
/*
* @dev Modifies `self` to contain the part of the string from the start of
* `self` to the end of the first occurrence of `needle`. If `needle`
* is not found, `self` is set to the empty slice.
* @param self The slice to search and modify.
* @param needle The text to search for.
* @return `self`.
*/
function rfind(slice self, slice needle) internal returns (slice) {
uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
self._len = ptr - self._ptr;
return self;
}
/*
* @dev Splits the slice, setting `self` to everything after the first
* occurrence of `needle`, and `token` to everything before it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and `token` is set to the entirety of `self`.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @param token An output parameter to which the first token is written.
* @return `token`.
*/
function split(slice self, slice needle, slice token) internal returns (slice) {
uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
token._ptr = self._ptr;
token._len = ptr - self._ptr;
if (ptr == self._ptr + self._len) {
// Not found
self._len = 0;
} else {
self._len -= token._len + needle._len;
self._ptr = ptr + needle._len;
}
return token;
}
/*
* @dev Splits the slice, setting `self` to everything after the first
* occurrence of `needle`, and returning everything before it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and the entirety of `self` is returned.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @return The part of `self` up to the first occurrence of `delim`.
*/
function split(slice self, slice needle) internal returns (slice token) {
split(self, needle, token);
}
/*
* @dev Splits the slice, setting `self` to everything before the last
* occurrence of `needle`, and `token` to everything after it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and `token` is set to the entirety of `self`.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @param token An output parameter to which the first token is written.
* @return `token`.
*/
function rsplit(slice self, slice needle, slice token) internal returns (slice) {
uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
token._ptr = ptr;
token._len = self._len - (ptr - self._ptr);
if (ptr == self._ptr) {
// Not found
self._len = 0;
} else {
self._len -= token._len + needle._len;
}
return token;
}
/*
* @dev Splits the slice, setting `self` to everything before the last
* occurrence of `needle`, and returning everything after it. If
* `needle` does not occur in `self`, `self` is set to the empty slice,
* and the entirety of `self` is returned.
* @param self The slice to split.
* @param needle The text to search for in `self`.
* @return The part of `self` after the last occurrence of `delim`.
*/
function rsplit(slice self, slice needle) internal returns (slice token) {
rsplit(self, needle, token);
}
/*
* @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.
* @param self The slice to search.
* @param needle The text to search for in `self`.
* @return The number of occurrences of `needle` found in `self`.
*/
function count(slice self, slice needle) internal returns (uint count) {
uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;
while (ptr <= self._ptr + self._len) {
count++;
ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;
}
}
/*
* @dev Returns True if `self` contains `needle`.
* @param self The slice to search.
* @param needle The text to search for in `self`.
* @return True if `needle` is found in `self`, false otherwise.
*/
function contains(slice self, slice needle) internal returns (bool) {
return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;
}
/*
* @dev Returns a newly allocated string containing the concatenation of
* `self` and `other`.
* @param self The first slice to concatenate.
* @param other The second slice to concatenate.
* @return The concatenation of the two strings.
*/
function concat(slice self, slice other) internal returns (string) {
var ret = new string(self._len + other._len);
uint retptr;
assembly { retptr := add(ret, 32) }
memcpy(retptr, self._ptr, self._len);
memcpy(retptr + self._len, other._ptr, other._len);
return ret;
}
/*
* @dev Joins an array of slices, using `self` as a delimiter, returning a
* newly allocated string.
* @param self The delimiter to use.
* @param parts A list of slices to join.
* @return A newly allocated string containing all the slices in `parts`,
* joined with `self`.
*/
function join(slice self, slice[] parts) internal returns (string) {
if (parts.length == 0)
return "";
uint len = self._len * (parts.length - 1);
for(uint i = 0; i < parts.length; i++)
len += parts[i]._len;
var ret = new string(len);
uint retptr;
assembly { retptr := add(ret, 32) }
for(i = 0; i < parts.length; i++) {
memcpy(retptr, parts[i]._ptr, parts[i]._len);
retptr += parts[i]._len;
if (i < parts.length - 1) {
memcpy(retptr, self._ptr, self._len);
retptr += self._len;
}
}
return ret;
}
}
+6 -6
View File
@@ -1,7 +1,7 @@
pragma solidity ^0.4.9;
import "lib/ethereans/management/Owned.sol";
import "Owned.sol";
pragma solidity ^0.4.11;
contract BountyBank is Owned {
enum State {CLOSED, OPEN, CLAIMED}
@@ -42,10 +42,10 @@ contract BountyBank is Owned {
bounties[num].points += points;
}
function close(uint num) only_owner {
function close(uint num, uint _closedAt) only_owner {
if(bounties[num].state == State.CLAIMED) throw;
bounties[num].state = State.CLOSED;
bounties[num].closedAt = now;
bounties[num].closedAt = _closedAt;
}
function claim(uint num){
-96
View File
@@ -1,96 +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/oraclizeAPI_0.4.sol";
import "lib/ethereans/management/Owned.sol";
import "./DGitDB.sol";
import "./GitHubAPI.sol";
import "./GitRepository.sol";
contract DGit is Owned, DGitI {
DGitDBI public db;
GitHubAPI public gitHubApi;
function initialize() only_owner {
db = DBFactory.newStorage();
gitHubApi = QueryFactory.newGitHubAPI();
}
function register(string _github_user, string _gistid) payable{
gitHubApi.register.value(msg.value)(msg.sender,_github_user,_gistid);
}
function updateCommits(string _repository) payable{
gitHubApi.updateCommits.value(msg.value)(_repository,db.getClaimedHead(_repository));
}
function addRepository(string _repository) payable{
gitHubApi.addRepository.value(msg.value)(_repository);
}
function updateIssue(string _repository, string issue) payable{
gitHubApi.updateIssue.value(msg.value)(_repository,issue);
}
function getRepository(uint projectId) constant returns (address){
return db.getRepositoryAddress(projectId);
}
function getRepository(string full_name) constant returns (address){
return db.getRepositoryAddress(full_name);
}
modifier only_gitapi{
if (msg.sender != address(gitHubApi)) throw;
_;
}
event UserSet(string githubLogin);
function __register(address addrLoaded, uint256 userId, string login)
only_gitapi {
UserSet(login);
db.addUser(userId, login, 0, addrLoaded);
}
event GitRepositoryRegistered(uint256 projectId, string full_name, uint256 watchers, uint256 subscribers);
function __setRepository(uint256 projectId, string full_name, uint256 watchers, uint256 subscribers) only_gitapi //[83725290, "ethereans/github-token", 4, 2]
{
uint256 ownerId; string memory name; //TODO
address repository = db.getRepositoryAddress(projectId);
if(repository == 0x0){
GitRepositoryRegistered(projectId,full_name,watchers,subscribers);
repository = GitFactory.newGitRepository(projectId,full_name);
db.addRepository(projectId,ownerId,name,full_name,repository);
}
GitRepositoryI(repository).setStats(subscribers,watchers);
}
event NewPoints(string repository, uint userId, uint total);
function __newPoints(string repository, uint userId, uint total)
only_gitapi {
NewPoints(repository,userId,total);
GitRepositoryI repoaddr = GitRepositoryI(db.getRepositoryAddress(repository));
if(!repoaddr.claim(db.getUserAddress(userId), total)){ //try to claim points
db.setPending(repository, userId, total); //set as a pending points
}
}
//claims pending points
function claimPending(uint repoId, uint userId){
GitRepositoryI repoaddr = GitRepositoryI(db.getRepositoryAddress(repoId));
uint total = db.claimPending(repoId,userId);
if(!repoaddr.claim(db.getUserAddress(userId), total)) throw;
}
}
-239
View File
@@ -1,239 +0,0 @@
pragma solidity ^0.4.9;
import "lib/oraclize/oraclizeAPI_0.4.sol";
import "lib/StringLib.sol";
import "lib/JSONLib.sol";
import "lib/ethereans/management/Owned.sol";
contract GitHubAPI{
function register(address _sender, string _github_user, string _gistid) payable;
function updateCommits(string _full_name, string _branch, bytes20 _commitid) payable;
function addRepository(string _full_name) payable;
function updateIssue(string _full_name, string _issue) payable;
}
contract DGitI {
function __register(address addrLoaded, uint256 userId, string login);
function __addRepository(uint256 projectId, string full_name, string default_branch);
function __setHead(uint256 projectId, string branch, bytes20 head);
function __setTail(uint256 projectId, string branch, bytes20 tail);
function __newPoints(uint256 projectId, uint256 userId, uint total);
function __setIssue(uint256 projectId, uint256 issueId, bool state, uint256 closedAt);
function __setIssuePoints(uint256 projectId, uint256 issueId, uint256 userId, uint256 points);
}
contract GitHubAPIOraclize is GitHubAPI, Owned, usingOraclize{
using StringLib for string;
DGitI dGit
string private cred = "f94095ba1d48038d4a81,36ae0e8b1bc5ad261c936e8f7f730f6c827c221f";
string private credentials = "?client_id=f94095ba1d48038d4a81&client_secret=36ae0e8b1bc5ad261c936e8f7f730f6c827c221f";
string private script = "QmU6pSQMDSg8do9eZLAfjzZYcC9JpsMZeB4ZoteGkSe94y";
enum OracleType { ADD_REPOSITORY, SET_USER, CLAIM_COMMIT, CLAIM_CONTINUE, 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
//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;
bytes20 commitid;
}
function GitHubAPIOraclize(){
dGit = DGitI(msg.sender);
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
}
//register or change a github user ethereum address. 100000000000000000
function register(address _sender, string _github_user, string _gistid)
payable only_owner{
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: _sender, githubid: _github_user});
}
function addRepository(string _repository)
payable only_owner{
bytes32 ocid = oraclize_query("URL", StringLib.concat("json(https://api.github.com/repos/",_repository,credentials,").$.id,full_name,default_branch"),4000000);
claimType[ocid] = OracleType.ADD_REPOSITORY;
}
function updateCommits(string _repository, string _branch, bytes20 _commitid)
payable only_owner{
bytes32 ocid = oraclize_query("computation", [script, "update-new",_repository.concat(",", _branch,",",toString(_commitid)),cred]);
claimType[ocid] = OracleType.CLAIM_COMMIT;
commitClaim[ocid] = CommitClaim( { repository: _repository, commitid:_commitid});
}
function continueUpdateCommits(string _repository, string _branch, bytes20 _lastCommit,bytes20 _limitCommit)
payable only_owner{
bytes32 ocid = oraclize_query("computation", [script, "update-old",_repository.concat(",", _branch,",",toString(_lastCommit)).concat(",",toString(_limitCommit)),cred]);
claimType[ocid] = OracleType.CLAIM_CONTINUE;
}
function updateIssue(string _repository, string issue) payable only_owner{
bytes32 ocid = oraclize_query("computation", [script, "issue-update",_repository.concat(",",issue),cred]);
}
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.ADD_REPOSITORY){
_addRepository(myid, result);
}else if(claimType[myid]==OracleType.CLAIM_COMMIT){
_updateCommits(myid, result, false);
}else if(claimType[myid]==OracleType.CLAIM_CONTINUE){
_updateCommits(myid, result, true);
}else if(claimType[myid] == OracleType.UPDATE_ISSUE){
_updateIssue(myid, result);
}
delete claimType[myid]; //should always be deleted
}
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){
dGit.__register(addrLoaded, userId, login);
}
delete userClaim[myid]; //should always be deleted
}
function _addRepository(bytes32 myid, string result) internal //[85743750, "ethereans/TheEtherian", "master"]
{
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint256 projectId;
(projectId,pos) = JSONLib.getNextUInt(v,pos);
string memory full_name;
(full_name,pos) = JSONLib.getNextString(v,pos);
string memory default_branch;
(default_branch,pos) = JSONLib.getNextString(v,pos);
dGit.__addRepository(projectId,full_name,default_branch);
}
function _updateCommits(bytes32 myid, string result, bool continuing)
internal {
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint256 projectId;
(projectId,pos) = JSONLib.getNextUInt(v,pos);
string memory branch;
(branch,pos) = JSONLib.getNextString(v,pos);
(temp,pos) = JSONLib.getNextString(v,pos);
bytes20 head = temp.toBytes20();
(temp,pos) = JSONLib.getNextString(v,pos);
bytes20 tail = temp.toBytes20();
uint numAuthors;
(numAuthors,pos) = JSONLib.getNextUInt(v,pos);
uint userId;
uint points;
dGit.__setHead(projectId,branch,head);
if(continuing){
dGit.__setTail(projectId,branch,tail);
}else{
bytes20 oldCommit = commitUpdate[myid].commitid;
if(oldCommit == 0x0){
dGit.__setTail(projectId,branch,tail);
}else if (oldCommit != tail){
//TODO: acceptContinueUpdateUntilLimit(tail,oldCommit)
}
}
for(uint i; i < numAuthors; i++){
(userId,pos) = JSONLib.getNextUInt(v,pos);
(points,pos) = JSONLib.getNextUInt(v,pos);
dGit.__newPoints(projectId,userId,points);
}
}
function _updateIssue(bytes32 myid, string result)
internal {
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint256 projectId;
(projectId,pos) = JSONLib.getNextUInt(v,pos);
uint256 issueId;
(issueId,pos) = JSONLib.getNextUInt(v,pos);
bool state;
(temp,pos) = JSONLib.getNextString(v,pos);
state = (temp.compare("open") == 0);
uint256 closedAt;
(closedAt,pos) = JSONLib.getNextUInt(v,pos);
uint numAuthors;
(numAuthors,pos) = JSONLib.getNextUInt(v,pos);
uint userId;
uint points;
dGit.__setIssue(projectId,issueId,state,closedAt);
for(uint i; i < numAuthors; i++){
(userId,pos) = JSONLib.getNextUInt(v,pos);
(points,pos) = JSONLib.getNextUInt(v,pos);
dGit.__setIssuePoints(projectId,issueId,userId,points);
}
}
//owner management
function setAPICredentials(string _client_id, string _client_secret)
only_owner {
cred = StringLib.concat(_client_id,",", _client_secret);
credentials = StringLib.concat("?client_id=",_client_id,"&client_secret="+_client_secret);
}
function setScript(string _script) only_owner{
script = _script;
}
function clearAPICredentials()
only_owner {
cred = "";
credentials = "";
}
function toString(bytes20 self) internal constant returns (string) {
bytes memory bytesString = new bytes(20);
uint charCount = 0;
for (uint j = 0; j < 20; j++) {
byte char = byte(bytes20(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);
}
}
library QueryFactory {
function newGitHubAPI() returns (GitHubAPI){
return new GitHubAPIOraclize();
}
}
+101
View File
@@ -0,0 +1,101 @@
/**
* GitHubAPIReg.sol
* Abstract Logic for GitHubOracle Registries.
* Ricardo Guilherme Schmidt <3esmit@gmail.com>
*/
import "Owned.sol";
import "oraclizeAPI_0.4.sol";
import "strings.sol";
pragma solidity ^0.4.11;
contract GitHubAPIReg is Owned, usingOraclize {
using strings for string;
using strings for strings.slice;
string cred = "";
event OracleEvent(bytes32 myid, string result, bytes proof);
function GitHubAPIReg(){
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
}
//owner management
function setAPICredentials(string _client_id, string _client_secret) only_owner {
strings.slice [] memory cm = new strings.slice[](5);
cm[0] = strings.toSlice("?client_id=");
cm[1] = _client_id.toSlice();
cm[2] = strings.toSlice("&client_secret=");
cm[4] = _client_secret.toSlice();
cred = strings.toSlice("").join(cm);
}
function clearAPICredentials() only_owner {
cred = "";
}
function getNextString(bytes _str, uint8 _pos) internal constant returns (string, uint8) {
uint8 start = 0;
uint8 end = 0;
uint strl =_str.length;
for (;strl > _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;
uint strl =_str.length;
for (; strl > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == ','){ //Find ends
_pos++; break;
}else if ((bp >= 48)&&(bp <= 57)){ //only ASCII numbers
val *= 10;
val += uint(bp) - 48;
}
}
return (val,_pos);
}
function getNextAddr(bytes _str, uint8 _pos) internal constant returns (address, uint8){
uint160 iaddr = 0;
uint strl =_str.length;
for(;strl > _pos; _pos++){
byte bp = _str[_pos];
if (bp == '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 (bp == ','){
_pos++;
break;
}
}
return (address(iaddr),_pos);
}
function hexVal(uint val) internal constant returns (uint){
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
}
+108
View File
@@ -0,0 +1,108 @@
/**
* GitHubOracle.sol
* 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 "oraclizeAPI_0.4.sol";
import "Owned.sol";
import "./GitHubUserReg.sol";
import "./GitHubRepositoryReg.sol";
import "./GitHubPoints.sol";
pragma solidity ^0.4.11;
contract GitHubOracle is Owned, DGitI {
GitHubUserReg public userReg;
GitHubRepositoryReg public repositoryReg;
GitHubPoints public gitHubPoints;
mapping (uint256 => Repository) repositories;
mapping (uint256 => mapping (uint256 => uint256)) pending;
modifier oraclized {
if(msg.sender != address(gitHubPoints)) throw;
_;
}
struct Repository {
string head;
string tail;
mapping (string => string) pending;
}
function initialize() only_owner {
if(address(userReg) == 0x0){
userReg = GHUserReg.create();
}else if(address(repositoryReg) == 0x0){
repositoryReg = GHRepoReg.create();
}else if(address(gitHubPoints) == 0x0){
gitHubPoints = GHPoints.create();
}else throw;
}
function update(string _repository, string _token) payable {
uint256 repoId = repositoryReg.getId(_repository);
if(repoId == 0) throw;
gitHubPoints.update.value(msg.value)(_repository, "master", repositories[repoId].head,_token);
}
function issue(string _repository, string _issue, string _token) payable {
gitHubPoints.issue.value(msg.value)(_repository,_issue,_token);
}
function __pendingScan(uint256 _projectId, string _lastCommit, string _pendingTail) oraclized {
repositories[_projectId].pending[_pendingTail] = _lastCommit;
}
function __setHead(uint256 _projectId, string _head) oraclized {
repositories[_projectId].head = _head;
}
function __setTail(uint256 _projectId, string _tail) oraclized {
repositories[_projectId].tail = _tail;
}
function __setIssue(uint256 _projectId, uint256 _issueId, bool _state, uint256 _closedAt) oraclized {
GitRepositoryI repo = GitRepositoryI(repositoryReg.getAddr(_projectId));
repo.setBounty(_issueId, _state, _closedAt);
}
function __setIssuePoints(uint256 _projectId, uint256 _issueId, uint256 _userId, uint256 _points) oraclized {
GitRepositoryI repo = GitRepositoryI(repositoryReg.getAddr(_projectId));
repo.setBountyPoints(_issueId, userReg.getAddr(_userId), _points);
}
event NewPoints(uint repoId, uint userId, uint total, bool claimed);
function __newPoints(uint _repoId, uint _userId, uint _points)
only_owner {
GitRepositoryI repoaddr = GitRepositoryI(repositoryReg.getAddr(_repoId));
bool claimed = repoaddr.claim(userReg.getAddr(_userId), _points);
if(!claimed){ //try to claim points
pending[_userId][_repoId] += _points; //set as a pending points
}
NewPoints(_repoId, _userId, _points, claimed);
}
//claims pending points
function claimPending(uint _repoId, uint _userId){
GitRepositoryI repoaddr = GitRepositoryI(repositoryReg.getAddr(_repoId));
uint total = pending[_userId][_repoId];
delete pending[_userId][_repoId];
if(repoaddr.claim(userReg.getAddr(_userId), total)) {
NewPoints(_repoId,_userId,total,true);
} else throw;
}
}
+281
View File
@@ -0,0 +1,281 @@
import "oraclizeAPI_0.4.sol";
import "Owned.sol";
import "strings.sol";
pragma solidity ^0.4.11;
contract DGitI {
function __setHead(uint256 projectId, string head);
function __setTail(uint256 projectId, string tail);
function __newPoints(uint256 projectId, uint256 userId, uint total);
function __pendingScan(uint256 projectId, string lastCommit, string pendingTail);
function __setIssue(uint256 projectId, uint256 issueId, bool state, uint256 closedAt);
function __setIssuePoints(uint256 projectId, uint256 issueId, uint256 userId, uint256 points);
}
contract GitHubPoints is Owned, usingOraclize{
using strings for string;
using strings for strings.slice;
string private cred = "";
string private script = "";
enum Command { UPDATE, RESUME, ISSUE }
mapping (bytes32 => Command) command; //temporary db enumerating oraclize calls
mapping (bytes32 => string) lastCommits; //temporary db for oraclize commit token claim calls
//stores temporary data for oraclize repository commit claim
struct CommitClaim {
string repository;
bytes20 commitid;
}
function update(string _repository, string _branch, string _lastCommit, string _cred) payable only_owner {
if(bytes(_cred).length == 0) _cred = cred;
bytes32 ocid = oraclize_query("nested", _query_update(_repository,_branch,_lastCommit,_cred));
command[ocid] = Command.UPDATE;
lastCommits[ocid] = _lastCommit;
}
function resume(string _repository, string _branch, string _lastCommit, string _limitCommit, string _cred)
payable only_owner {
if(bytes(_cred).length == 0) _cred = cred;
bytes32 ocid = oraclize_query("nested", _query_resume(_repository,_branch,_lastCommit,_limitCommit,_cred));
command[ocid] = Command.RESUME;
lastCommits[ocid] = _lastCommit;
}
function issue(string _repository, string _issue, string _cred)
payable only_owner {
if(bytes(_cred).length == 0) _cred = cred;
command[ocid] = Command.ISSUE;
bytes32 ocid = oraclize_query("nested", _query_issue(_repository,_issue,_cred));
}
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;
Command comm = command[myid];
if(comm == Command.UPDATE) {
_update(lastCommits[myid], result);
}else if(comm == Command.ISSUE) {
_issue(result);
}else if (comm == Command.RESUME) {
_resume(lastCommits[myid], result);
delete lastCommits[myid];
}
delete command[myid];
}
function _update(string _lastCommit, string result) internal {
DGitI dGit = DGitI(owner);
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint256 projectId;
(projectId,pos) = getNextUInt(v,pos);
(temp,pos) = getNextString(v,pos); //branch
(temp,pos) = getNextString(v,pos); //head
dGit.__setHead(projectId,temp); //head
(temp,pos) = getNextString(v,pos); //tail
if(bytes(_lastCommit).length == 0){
dGit.__setTail(projectId,temp);
}
if (sha3(_lastCommit) != sha3(temp)){ //update didn't reached _lastCommit
dGit.__pendingScan(projectId,_lastCommit,temp);
}
uint numAuthors;
(numAuthors,pos) = getNextUInt(v,pos);
uint userId;
uint points;
for(uint i; i < numAuthors; i++){
(userId,pos) = getNextUInt(v,pos);
(points,pos) = getNextUInt(v,pos);
dGit.__newPoints(projectId,userId,points);
}
}
function _resume(string _lastCommit, string result) internal {
DGitI dGit = DGitI(owner);
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint256 projectId;
(projectId,pos) = getNextUInt(v,pos);
string memory branch;
(branch,pos) = getNextString(v,pos);
string memory head;
(head,pos) = getNextString(v,pos);
string memory tail;
(tail,pos) = getNextString(v,pos);
dGit.__setTail(projectId,tail);
uint numAuthors;
(numAuthors,pos) = getNextUInt(v,pos);
uint userId;
uint points;
for(uint i; i < numAuthors; i++){
(userId,pos) = getNextUInt(v,pos);
(points,pos) = getNextUInt(v,pos);
dGit.__newPoints(projectId,userId,points);
}
}
function _issue(string result) internal {
DGitI dGit = DGitI(owner);
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint256 projectId;
(projectId,pos) = getNextUInt(v,pos);
uint256 issueId;
(issueId,pos) = getNextUInt(v,pos);
bool state;
(temp,pos) = getNextString(v,pos);
state = (sha3("open") == sha3(temp));
uint256 closedAt;
(closedAt,pos) = getNextUInt(v,pos);
uint numAuthors;
(numAuthors,pos) = getNextUInt(v,pos);
uint userId;
uint points;
dGit.__setIssue(projectId,issueId,state,closedAt);
for(uint i; i < numAuthors; i++){
(userId,pos) = getNextUInt(v,pos);
(points,pos) = getNextUInt(v,pos);
dGit.__setIssuePoints(projectId,issueId,userId,points);
}
}
//owner management
function GitHubPoints(string _script){
script = _script;
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
}
function setAPICredentials(string _client_id_comma_client_secret) only_owner {
cred = _client_id_comma_client_secret;
}
function setScript(string _script) only_owner{
script = _script;
}
function clearAPICredentials() only_owner {
cred = "";
}
function _query_script(string command, string args, string cred) internal returns (string) {
strings.slice memory comma = strings.toSlice("', '");
strings.slice [] memory cm = new strings.slice[](4);
cm[0] = script.toSlice();
cm[1] = command.toSlice();
cm[2] = args.toSlice();
cm[3] = cred.toSlice();
string memory array = comma.join(cm);
cm = new strings.slice[](3);
cm[0] = strings.toSlice("[computation] ['");
cm[1] = array.toSlice();
cm[2] = strings.toSlice("']");
return strings.toSlice("").join(cm);
}
function _query_update(string _repository, string _branch, string _lastCommit, string _cred) internal returns (string) {
strings.slice memory comma = strings.toSlice(",");
strings.slice [] memory cm = new strings.slice[](3);
cm[0] = _repository.toSlice();
cm[1] = _branch.toSlice();
cm[2] = _lastCommit.toSlice();
return _query_script("update",comma.join(cm),_cred);
}
function _query_resume(string _repository, string _branch, string _lastCommit, string _limitCommit, string _cred) internal constant returns (string){
strings.slice memory comma = strings.toSlice(",");
strings.slice [] memory cm = new strings.slice[](4);
cm[0] = _repository.toSlice();
cm[1] = _branch.toSlice();
cm[2] = _lastCommit.toSlice();
cm[3] = _limitCommit.toSlice();
return _query_script("resume",comma.join(cm),_cred);
}
function _query_issue(string _repository, string _issue, string _cred) internal returns(string){
strings.slice memory comma = strings.toSlice(",");
strings.slice [] memory cm = new strings.slice[](2);
cm[0] = _repository.toSlice();
cm[1] = _issue.toSlice();
return _query_script("resume",comma.join(cm),_cred);
}
function toBytes20(string memory source) internal constant returns (bytes20 result) {
assembly {
result := mload(add(source, 20))
}
}
function toString(bytes20 self) internal constant returns (string) {
bytes memory bytesString = new bytes(20);
uint charCount = 0;
for (uint j = 0; j < 20; j++) {
byte char = byte(bytes20(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);
}
function getNextString(bytes _str, uint8 _pos) internal constant returns (string, uint8) {
uint8 start = 0;
uint8 end = 0;
uint strl =_str.length;
for (;strl > _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;
uint strl =_str.length;
for (; strl > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == ','){ //Find ends
_pos++; break;
}else if ((bp >= 48)&&(bp <= 57)){ //only ASCII numbers
val *= 10;
val += uint(bp) - 48;
}
}
return (val,_pos);
}
}
library GHPoints {
function create() returns (GitHubPoints){
return new GitHubPoints("");
}
}
-160
View File
@@ -1,160 +0,0 @@
//Author: Ricardo Guilherme Schmidt <3esmit@gmail.com>
pragma solidity ^0.4.11;
import "lib/oraclize/oraclizeAPI_0.4.sol";
import "lib/ethereans/management/Owned.sol";
contract GitHubRegisterEth is Owned, usingOraclize{
string private credentials = "";
mapping (bytes32 => UserClaim) userClaim; //temporary db for oraclize user register queries
mapping (bytes32 => uint256) indexes;
mapping (uint256 => User) users;
event RegisterUpdated(string name);
//stores temporary data for oraclize user register request
struct UserClaim {
address sender;
string login;
}
struct User {
address addr;
string login;
}
function GitHubRegisterEth(){
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
}
function register(string _github_user, string _gistid) payable {
bytes32 ocid = oraclize_query("nested", _getQuery(_github_user, _gistid));
userClaim[ocid] = UserClaim({sender: msg.sender, login: _github_user});
}
function getAddr(uint256 _id) public constant returns(address addr) {
return users[_id].addr;
}
function getName(address _addr) public constant returns(string name){
return users[indexes[sha3(_addr)]].login;
}
function getAddr(string _name) public constant returns(address addr) {
return users[indexes[sha3(_name)]].addr;
}
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 {
_register(myid, result);
}
}
function _register(bytes32 myid, string result) internal {
bytes memory v = bytes(result);
uint8 pos = 0;
address addrLoaded;
string memory login;
uint256 userId;
(addrLoaded,pos) = getNextAddr(v,pos);
(login,pos) = getNextString(v,pos);
(userId,pos) = getNextUInt(v,pos);
if(userClaim[myid].sender == addrLoaded && sha3(userClaim[myid].login) == sha3(login)){
RegisterUpdated(login);
if(users[userId].addr != 0x0){
delete indexes[sha3(users[userId].login)];
delete indexes[sha3(users[userId].addr)];
}
indexes[sha3(addrLoaded)] = userId;
indexes[sha3(login)] = userId;
users[userId].addr = addrLoaded;
users[userId].login = login;
}
delete userClaim[myid]; //should always be deleted
}
//owner management
function setAPICredentials(string _client_id, string _client_secret) only_owner {
credentials = strConcat("?client_id=",_client_id,"&client_secret=",_client_secret,"");
}
function clearAPICredentials() only_owner {
credentials = "";
}
//internal helper functions
function _getQuery(string _github_user, string _gistid) internal constant returns (string){
string memory a = strConcat("[identity] ${[URL] https://gist.githubusercontent.com/", _github_user,"/",_gistid,"/raw/registereth.txt}, ${[URL] json(https://api.github.com/gists/");
return strConcat(a, _gistid, credentials, ").owner.[login,id]}","");
}
function getNextString(bytes _str, uint8 _pos) internal constant returns (string,uint8) {
uint8 start = 0;
uint8 end = 0;
uint strl =_str.length;
for (;strl > _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;
uint strl =_str.length;
for (; strl > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == ','){ //Find ends
_pos++; break;
}else if ((bp >= 48)&&(bp <= 57)){ //only ASCII numbers
val *= 10;
val += uint(bp) - 48;
}
}
return (val,_pos);
}
function getNextAddr(bytes _str, uint8 _pos) internal constant returns (address, uint8){
uint160 iaddr = 0;
uint strl =_str.length;
for(;strl > _pos; _pos++){
byte bp = _str[_pos];
if (bp == '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 (bp == ','){
_pos++;
break;
}
}
return (address(iaddr),_pos);
}
function hexVal(uint val) internal constant returns (uint){
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
}
+103
View File
@@ -0,0 +1,103 @@
/**
* GitHubRepositoryReg.sol
* Registers the master branch of a Repository for GitHubOracle tracking.
* Ricardo Guilherme Schmidt <3esmit@gmail.com>
*/
import "./GitHubAPIReg.sol";
import "./NameRegistry.sol";
import "./GitRepository.sol";
import "strings.sol";
pragma solidity ^0.4.11;
contract GitHubRepositoryReg is NameRegistry, GitHubAPIReg {
using strings for string;
using strings for strings.slice;
mapping (uint256 => Repository) public repositories;
event NewRepository(address addr, uint256 projectId, string full_name, string default_branch);
struct Repository {
address addr;
string name;
string branch;
}
function register(string _repository, string _cred) payable {
if(bytes(_cred).length == 0) _cred = cred;
uint gas = getAddr(_repository) == 0x00? 4000000 : 1000000;
oraclize_query("URL", _query_script(_repository,_cred), gas);
}
function getAddr(uint256 _id) public constant returns(address addr) {
return repositories[_id].addr;
}
function getName(address _addr) public constant returns(string name){
return repositories[indexes[sha3(_addr)]].name;
}
function getAddr(string _name) public constant returns(address addr) {
return repositories[indexes[sha3(_name)]].addr;
}
function getBranch(uint256 _id) public constant returns(string branch) {
return repositories[_id].branch;
}
//oraclize response callback
function __callback(bytes32 myid, string result, bytes proof) {
OracleEvent(myid,result,proof);
if (msg.sender != oraclize.cbAddress()){
throw;
}else {
_setRepository(result);
}
}
function _setRepository(string result) internal //[85743750, "ethereans/TheEtherian", "master"]
{
bytes memory v = bytes(result);
uint8 pos = 0;
uint256 projectId;
(projectId,pos) = getNextUInt(v,pos);
string memory full_name;
(full_name,pos) = getNextString(v,pos);
string memory default_branch;
(default_branch,pos) = getNextString(v,pos);
address repoAddr = repositories[projectId].addr;
if(repoAddr == 0x0){
GitRepositoryI repo = GitFactory.newGitRepository(projectId, full_name);
repo.setOwner(owner);
repoAddr = address(repo);
indexes[sha3(repoAddr)] = projectId;
indexes[sha3(full_name)] = projectId;
NewRepository(repoAddr, projectId, full_name, default_branch);
repositories[projectId] = Repository({addr: repoAddr, name: full_name, branch: default_branch});
}else{
bytes32 _new = sha3(full_name);
bytes32 _old = sha3(repositories[projectId].name);
if(_new != _old){
_updateIndex(_old, _new);
}
}
}
//internal helper functions
function _query_script(string _repository, string _cred) internal returns (string) {
strings.slice [] memory cm = new strings.slice[](5);
cm[0] = strings.toSlice("json(https://api.github.com/repos/");
cm[1] = _repository.toSlice();
cm[2] = _cred.toSlice();
cm[4] = strings.toSlice(").$.id,full_name,default_branch");
return strings.toSlice("").join(cm);
}
}
library GHRepoReg {
function create() returns (GitHubRepositoryReg){
return new GitHubRepositoryReg();
}
}
+104
View File
@@ -0,0 +1,104 @@
/**
* GitHubUserReg.sol
* Registers GitHub user login to an address
* Ricardo Guilherme Schmidt <3esmit@gmail.com>
*/
import "GitHubAPIReg.sol";
import "NameRegistry.sol";
import "strings.sol";
pragma solidity ^0.4.11;
contract GitHubUserReg is NameRegistry, GitHubAPIReg {
using strings for string;
using strings for strings.slice;
mapping (bytes32 => UserClaim) userClaim; //temporary db for oraclize user register queries
mapping (uint256 => User) users;
event RegisterUpdated(string name);
//stores temporary data for oraclize user register request
struct UserClaim {
address sender;
string login;
}
struct User {
address addr;
string login;
}
function register(string _github_user, string _gistid, string _cred) payable {
if(bytes(_cred).length == 0) _cred = cred;
bytes32 ocid = oraclize_query("nested", _query_script(_github_user, _gistid,_cred));
userClaim[ocid] = UserClaim({sender: msg.sender, login: _github_user});
}
function getAddr(uint256 _id) public constant returns(address addr) {
return users[_id].addr;
}
function getName(address _addr) public constant returns(string name){
return users[indexes[sha3(_addr)]].login;
}
function getAddr(string _name) public constant returns(address addr) {
return users[indexes[sha3(_name)]].addr;
}
//oraclize response callback
function __callback(bytes32 myid, string result, bytes proof) {
OracleEvent(myid, result, proof);
if (msg.sender != oraclize.cbAddress()){
throw;
}else {
_register(myid, result);
}
}
function _register(bytes32 myid, string result) internal {
bytes memory v = bytes(result);
uint8 pos = 0;
address addrLoaded;
string memory login;
uint256 userId;
(addrLoaded,pos) = getNextAddr(v,pos);
(login,pos) = getNextString(v,pos);
(userId,pos) = getNextUInt(v,pos);
if(userClaim[myid].sender == addrLoaded && sha3(userClaim[myid].login) == sha3(login)){
RegisterUpdated(login);
if(users[userId].addr != 0x0){
delete indexes[sha3(users[userId].login)];
delete indexes[sha3(users[userId].addr)];
}
indexes[sha3(addrLoaded)] = userId;
indexes[sha3(login)] = userId;
users[userId].addr = addrLoaded;
users[userId].login = login;
}
delete userClaim[myid]; //should always be deleted
}
function _query_script(string _github_user, string _gistid, string _cred) internal returns (string) {
strings.slice [] memory cm = new strings.slice[](8);
cm[0] = strings.toSlice("[identity] ${[URL] https://gist.githubusercontent.com/");
cm[1] = _github_user.toSlice();
cm[2] = strings.toSlice("/");
cm[3] = _gistid.toSlice();
cm[4] = strings.toSlice("/raw/register.txt}, ${[URL] json(https://api.github.com/gists/");
cm[5] = _gistid.toSlice();
cm[6] = _cred.toSlice();
cm[7] = strings.toSlice(").owner.[login,id]}");
return strings.toSlice("").join(cm);
}
}
library GHUserReg{
function create() returns (GitHubUserReg){
return new GitHubUserReg();
}
}
+14 -24
View File
@@ -1,5 +1,3 @@
pragma solidity ^0.4.8;
/**
* Contract that mint tokens by github commit stats
*
@@ -15,18 +13,20 @@ pragma solidity ^0.4.8;
* Released under GPLv3 License
*/
import "lib/ethereans/bank/CollaborationBank.sol";
import "lib/ethereans/management/Owned.sol";
import "CollaborationBank.sol";
import "Owned.sol";
import "./BountyBank.sol";
import "./GitRepositoryToken.sol";
pragma solidity ^0.4.11;
contract GitRepositoryI {
contract GitRepositoryI is Owned{
function claim(address _user, uint _total) returns (bool) ;
function setStats(uint256 _subscribers, uint256 _watchers);
function setBounty(uint256 _issueId, bool _state, uint256 _closedAt);
function setBountyPoints(uint256 _issueId, address _claimer, uint256 _points);
}
contract GitRepository is GitRepositoryI, Owned {
contract GitRepository is GitRepositoryI {
GitRepositoryToken public token;
CollaborationBank public donationBank;
@@ -36,9 +36,6 @@ contract GitRepository is GitRepositoryI, Owned {
string public name;
uint256 public uid;
uint256 public subscribers;
uint256 public watchers;
function () payable {
donationBank.deposit();
donators[msg.sender] += msg.value;
@@ -53,7 +50,6 @@ contract GitRepository is GitRepositoryI, Owned {
bountyBank = new BountyBank();
}
//oracle claim request
function claim(address _user, uint _total)
only_owner returns (bool) {
@@ -65,21 +61,15 @@ contract GitRepository is GitRepositoryI, Owned {
}
}
function setStats(uint256 _subscribers, uint256 _watchers)
only_owner {
subscribers = _subscribers;
watchers = _watchers;
}
function bountyState(uint issue, bool open) only_owner {
if (open) bountyBank.open(issue);
else bountyBank.close(issue);
}
function bountyState(uint issue, address claimer, uint points) only_owner {
bountyBank.setClaimer(issue,claimer,points);
function setBounty(uint256 _issueId, bool _state, uint256 _closedAt) only_owner {
if (_state) bountyBank.open(_issueId);
else bountyBank.close(_issueId,_closedAt);
}
function setBountyPoints(uint256 _issueId, address _claimer, uint256 _points) only_owner {
bountyBank.setClaimer(_issueId,_claimer,_points);
}
}
library GitFactory {
+4 -4
View File
@@ -1,5 +1,3 @@
pragma solidity ^0.4.8;
/**
* Contract that mint tokens by github commit stats
*
@@ -15,8 +13,10 @@ pragma solidity ^0.4.8;
* Released under GPLv3 License
*/
import "lib/ethereans/token/LockerToken.sol";
import "lib/ethereans/management/Owned.sol";
import "LockerToken.sol";
import "Owned.sol";
pragma solidity ^0.4.11;
contract GitRepositoryToken is LockerToken {
+27
View File
@@ -0,0 +1,27 @@
/**
* NameRegistry.sol
* Interface for Name Registries.
* Ricardo Guilherme Schmidt <3esmit@gmail.com>
*/
pragma solidity ^0.4.11;
contract NameRegistry {
function getAddr(uint256 _id) public constant returns(address addr);
function getAddr(string _name) public constant returns(address addr);
function getName(address _addr) public constant returns(string name);
mapping (bytes32 => uint256) indexes;
function getId(address _addr) public constant returns(uint256 id){
return indexes[sha3(_addr)];
}
function getId(string _name) public constant returns(uint256 id) {
return indexes[sha3(_name)];
}
function _updateIndex(bytes32 _old, bytes32 _new) internal {
indexes[_new] = indexes[_old];
delete indexes[_old];
}
}
+521
View File
@@ -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>