Files
gitpivot/contracts/src/GitHubAPI.sol
T
2017-04-06 19:24:03 +00:00

199 lines
7.6 KiB
Solidity

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 claimCommit(string _repository, string _commitid) payable;
function addRepository(string _repository) payable;
function updateIssue(string _repository, string issue) payable;
}
contract DGitI {
function __register(address addrLoaded, uint256 userId, string login);
function __setRepository(uint256 projectId, string full_name, uint256 watchers, uint256 subscribers);
function __claimCommit(string repository, bytes20 commitid, uint userid, uint total);
}
contract GitHubAPIOraclize is GitHubAPI, Owned, usingOraclize{
using StringLib for string;
DGitI dGit;
function GitHubAPIOraclize(){
dGit = DGitI(msg.sender);
}
string private credentials = ""; //store encrypted values of api access credentials
string private cred = "";
string private secret = "";
string private client = "";
string private script = "QmS3kHrUQ12ovovKPk9vxKjDPm7kVWcieaMcZc9w8JbNQt";
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
//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;
}
//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 updateCommits(string _repository, bytes20 _commitid)
payable only_owner{
string memory cred = StringLib.concat(" -c ${[decrypt] ", _client_id,"} -s ${[decrypt] ", _client_secret,"}");
string memory commit_url = StringLib.concat("-S update-commits -r",_repository," -H ", toString(_commitid), cred);
bytes32 ocid = oraclize_query("computation", ['']);
claimType[ocid] = OracleType.CLAIM_COMMIT;
commitClaim[ocid] = CommitClaim( { repository: _repository, commitid:_commitid});
}
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,watchers,subscribers_count"),4000000);
claimType[ocid] = OracleType.SET_REPOSITORY;
}
function updateIssue(string _repository, string issue) payable only_owner{
bytes32 ocid = oraclize_query("computation", [script, StringLib.concat("--reponame ",_repository, " --issueid ", issue, " --script issue-update").concat(" --client ", client, " --secret ", secret)]);
}
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){
_updateCommits(myid, result);
}else if(claimType[myid] == OracleType.SET_REPOSITORY){
_setRepository(myid, result);
}else if(claimType[myid] == OracleType.UPDATE_ISSUE){
_updateIssue(myid, result);
}
delete claimType[myid]; //should always be deleted
}
function _updateIssue(bytes32 myid, string result)
internal {
}
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 _setRepository(bytes32 myid, string result) internal //[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);
dGit.__setRepository(projectId,full_name,watchers,subscribers);
}
function _updateCommits(bytes32 myid, string result)
internal {
bytes memory v = bytes(result);
uint8 pos = 0;
string memory temp;
uint numAuthors;
(temp,pos) = JSONLib.getNextString(v,pos);
bytes20 head = temp.toBytes20();
(temp,pos) = JSONLib.getNextString(v,pos);
bytes20 tail = temp.toBytes20();
(numAuthors,pos) = JSONLib.getNextUInt(v,pos);
uint userId;
uint points;
for(uint i; i < numAuthors; i++){
(userId,pos) = JSONLib.getNextUInt(v,pos);
(points,pos) = JSONLib.getNextUInt(v,pos);
dGit._setCommiter(commitClaim[myid].repository,userId,points);
}
delete commitClaim[myid];
}
//owner management
function setAPICredentials(string _client_id, string _client_secret)
only_owner {
client = _client_id;
secret = _client_secret;
cred = StringLib.concat(" -c ${[decrypt] ", _client_id,"} -s ${[decrypt] ", _client_secret,"}");
credentials = StringLib.concat("?client_id=${[decrypt] ", _client_id,"}&client_secret=${[decrypt] ", _client_secret,"}");
}
function setScript(string _script) only_owner{
script = _script;
}
function clearAPICredentials()
only_owner {
credentials = "";
cred = "";
}
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();
}
}