Merge pull request #1 from ethereans/master

Pull changes from origin
This commit is contained in:
Ricardo Guilherme Schmidt
2017-03-23 14:59:30 -03:00
committed by GitHub
40 changed files with 2127 additions and 445 deletions
+4 -4
View File
@@ -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.
-66
View File
@@ -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;
}
}
-200
View File
@@ -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 = "";
}
}
-91
View File
@@ -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);
}
}
+23
View File
@@ -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);
}
}
+27
View File
@@ -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);
}
}
+65
View File
@@ -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
}
}
+147
View File
@@ -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
View File
@@ -1 +0,0 @@
../../../../abstract-token/contracts/
+10
View File
@@ -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);
}
}
+14
View File
@@ -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
View File
@@ -1 +0,0 @@
../../../../oraclize/ethereum-api
+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>
+71
View File
@@ -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]
}
}
+187
View File
@@ -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
View File
@@ -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
}
}
}
}
-15
View File
@@ -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
+143
View File
@@ -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
-25
View File
@@ -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
-14
View File
@@ -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==
-16
View File
@@ -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="
+5
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
# TheEtherian
+112
View File
@@ -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)