Transaction Hash:
Block:
4877687 at Jan-09-2018 02:48:48 AM +UTC
Transaction Fee:
0.00653772 ETH
$14.01
Gas Used:
108,962 Gas / 60 Gwei
Emitted Events:
| 42 |
FiCoin.OraclizeQuery( description=Oraclize query was sent, standing by for the answer. )
|
| 43 |
Oraclize.0xb76d0edd90c6a07aa3ff7a222d7f5933e29c6acc660c059c97837f05c4ca1a84( 0xb76d0edd90c6a07aa3ff7a222d7f5933e29c6acc660c059c97837f05c4ca1a84, 0000000000000000000000004c251de85ad3498c5b89388d8efc696ddd0b0fe7, 704a632020b893878cd8a7c4c7a5a00f3b4ef2762335c2841af7bbd5c9dbc5e9, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000100, 0000000000000000000000000000000000000000000000000000000000000140, 0000000000000000000000000000000000000000000000000000000000030d40, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000003, 55524c0000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000042, 6a736f6e2868747470733a2f2f6170692e636f696e6d61726b65746361702e63, 6f6d2f76312f7469636b65722f657468657265756d292e302e70726963655f75, 7364000000000000000000000000000000000000000000000000000000000000 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x3dBDc81a...e395fDcf6 | 4.322119 Eth | 4.33014 Eth | 0.008021 | ||
| 0x4c251de8...ddD0b0fE7 | 1,450.817828955313827645 Eth | 1,450.909807955313827645 Eth | 0.091979 | ||
| 0x8439469d...192387273 |
0.12865052 Eth
Nonce: 1
|
0.0221128 Eth
Nonce: 2
| 0.10653772 | ||
|
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 668.586415994877061107 Eth | 668.592953714877061107 Eth | 0.00653772 |
Execution Trace
ETH 0.1
FiCoin.CALL( )
-
OraclizeAddrResolver.CALL( ) -
Oraclize.524f3889( ) -
OraclizeAddrResolver.CALL( ) -
Oraclize.524f3889( ) - ETH 0.008021
Oraclize.adf59f99( )
[FiCoin (ln:1232)]
buyTokens[FiCoin (ln:1233)]oraclize_getPrice[FiCoin (ln:1243)]OraclizeQuery[FiCoin (ln:1244)]OraclizeQuery[FiCoin (ln:1246)]oraclize_query[FiCoin (ln:1247)]Contributor[FiCoin (ln:1248)]
File 1 of 3: FiCoin
File 2 of 3: Oraclize
File 3 of 3: OraclizeAddrResolver
pragma solidity ^0.4.18;
contract OraclizeI {
address public cbAddress;
function query(uint _timestamp, string _datasource, string _arg) external payable returns (bytes32 _id);
function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit) external payable returns (bytes32 _id);
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2) public payable returns (bytes32 _id);
function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit) external payable returns (bytes32 _id);
function queryN(uint _timestamp, string _datasource, bytes _argN) public payable returns (bytes32 _id);
function queryN_withGasLimit(uint _timestamp, string _datasource, bytes _argN, uint _gaslimit) external payable returns (bytes32 _id);
function getPrice(string _datasource) public returns (uint _dsprice);
function getPrice(string _datasource, uint gaslimit) public returns (uint _dsprice);
function setProofType(byte _proofType) external;
function setCustomGasPrice(uint _gasPrice) external;
function randomDS_getSessionPubKeyHash() external constant returns(bytes32);
}
contract OraclizeAddrResolverI {
function getAddress() public 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 proofType_Android = 0x20;
byte constant proofType_Ledger = 0x30;
byte constant proofType_Native = 0xF0;
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);
if(address(oraclize) != OAR.getAddress())
oraclize = OraclizeI(OAR.getAddress());
_;
}
modifier coupon(string code){
oraclize = OraclizeI(OAR.getAddress());
_;
}
function oraclize_setNetwork(uint8 networkID) internal returns(bool){
return oraclize_setNetwork();
networkID; // silence the warning and remain backwards compatible
}
function oraclize_setNetwork() internal returns(bool){
if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet
OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
oraclize_setNetworkName("eth_mainnet");
return true;
}
if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){ //ropsten testnet
OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1);
oraclize_setNetworkName("eth_ropsten3");
return true;
}
if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){ //kovan testnet
OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e);
oraclize_setNetworkName("eth_kovan");
return true;
}
if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48)>0){ //rinkeby testnet
OAR = OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48);
oraclize_setNetworkName("eth_rinkeby");
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) public {
__callback(myid, result, new bytes(0));
}
function __callback(bytes32 myid, string result, bytes proof) public {
return;
myid; result; proof; // Silence compiler warnings
}
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_query(string datasource, bytes[] 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 = ba2cbor(argN);
return oraclize.queryN.value(price)(0, datasource, args);
}
function oraclize_query(uint timestamp, string datasource, bytes[] 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 = ba2cbor(argN);
return oraclize.queryN.value(price)(timestamp, datasource, args);
}
function oraclize_query(uint timestamp, string datasource, bytes[] 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 = ba2cbor(argN);
return oraclize.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit);
}
function oraclize_query(string datasource, bytes[] 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 = ba2cbor(argN);
return oraclize.queryN_withGasLimit.value(price)(0, datasource, args, gaslimit);
}
function oraclize_query(string datasource, bytes[1] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[1] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[2] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[2] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[3] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[3] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[4] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[4] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[5] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[5] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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, bytes[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](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_randomDS_getSessionPubKeyHash() oraclizeAPI internal returns (bytes32){
return oraclize.randomDS_getSessionPubKeyHash();
}
function getCodeSize(address _addr) constant internal returns(uint _size) {
assembly {
_size := extcodesize(_addr)
}
}
function parseAddr(string _a) internal pure 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 >= 65)&&(b1 <= 70)) b1 -= 55;
else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48;
if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87;
else if ((b2 >= 65)&&(b2 <= 70)) b2 -= 55;
else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48;
iaddr += (b1*16+b2);
}
return address(iaddr);
}
function strCompare(string _a, string _b) internal pure 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 pure 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 pure 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 pure returns (string) {
return strConcat(_a, _b, _c, _d, "");
}
function strConcat(string _a, string _b, string _c) internal pure returns (string) {
return strConcat(_a, _b, _c, "", "");
}
function strConcat(string _a, string _b) internal pure returns (string) {
return strConcat(_a, _b, "", "", "");
}
// parseInt
function parseInt(string _a) internal pure returns (uint) {
return parseInt(_a, 0);
}
// parseInt(parseFloat*10^_b)
function parseInt(string _a, uint _b) internal pure 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 pure 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 pure 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;
}
function ba2cbor(bytes[] arr) internal pure 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;
}
string oraclize_network_name;
function oraclize_setNetworkName(string _network_name) internal {
oraclize_network_name = _network_name;
}
function oraclize_getNetworkName() internal view returns (string) {
return oraclize_network_name;
}
function oraclize_newRandomDSQuery(uint _delay, uint _nbytes, uint _customGasLimit) internal returns (bytes32){
require((_nbytes > 0) && (_nbytes <= 32));
bytes memory nbytes = new bytes(1);
nbytes[0] = byte(_nbytes);
bytes memory unonce = new bytes(32);
bytes memory sessionKeyHash = new bytes(32);
bytes32 sessionKeyHash_bytes32 = oraclize_randomDS_getSessionPubKeyHash();
assembly {
mstore(unonce, 0x20)
mstore(add(unonce, 0x20), xor(blockhash(sub(number, 1)), xor(coinbase, timestamp)))
mstore(sessionKeyHash, 0x20)
mstore(add(sessionKeyHash, 0x20), sessionKeyHash_bytes32)
}
bytes[3] memory args = [unonce, nbytes, sessionKeyHash];
bytes32 queryId = oraclize_query(_delay, "random", args, _customGasLimit);
oraclize_randomDS_setCommitment(queryId, keccak256(bytes8(_delay), args[1], sha256(args[0]), args[2]));
return queryId;
}
function oraclize_randomDS_setCommitment(bytes32 queryId, bytes32 commitment) internal {
oraclize_randomDS_args[queryId] = commitment;
}
mapping(bytes32=>bytes32) oraclize_randomDS_args;
mapping(bytes32=>bool) oraclize_randomDS_sessionKeysHashVerified;
function verifySig(bytes32 tosignh, bytes dersig, bytes pubkey) internal returns (bool){
bool sigok;
address signer;
bytes32 sigr;
bytes32 sigs;
bytes memory sigr_ = new bytes(32);
uint offset = 4+(uint(dersig[3]) - 0x20);
sigr_ = copyBytes(dersig, offset, 32, sigr_, 0);
bytes memory sigs_ = new bytes(32);
offset += 32 + 2;
sigs_ = copyBytes(dersig, offset+(uint(dersig[offset-1]) - 0x20), 32, sigs_, 0);
assembly {
sigr := mload(add(sigr_, 32))
sigs := mload(add(sigs_, 32))
}
(sigok, signer) = safer_ecrecover(tosignh, 27, sigr, sigs);
if (address(keccak256(pubkey)) == signer) return true;
else {
(sigok, signer) = safer_ecrecover(tosignh, 28, sigr, sigs);
return (address(keccak256(pubkey)) == signer);
}
}
function oraclize_randomDS_proofVerify__sessionKeyValidity(bytes proof, uint sig2offset) internal returns (bool) {
bool sigok;
// Step 6: verify the attestation signature, APPKEY1 must sign the sessionKey from the correct ledger app (CODEHASH)
bytes memory sig2 = new bytes(uint(proof[sig2offset+1])+2);
copyBytes(proof, sig2offset, sig2.length, sig2, 0);
bytes memory appkey1_pubkey = new bytes(64);
copyBytes(proof, 3+1, 64, appkey1_pubkey, 0);
bytes memory tosign2 = new bytes(1+65+32);
tosign2[0] = byte(1); //role
copyBytes(proof, sig2offset-65, 65, tosign2, 1);
bytes memory CODEHASH = hex"fd94fa71bc0ba10d39d464d0d8f465efeef0a2764e3887fcc9df41ded20f505c";
copyBytes(CODEHASH, 0, 32, tosign2, 1+65);
sigok = verifySig(sha256(tosign2), sig2, appkey1_pubkey);
if (sigok == false) return false;
// Step 7: verify the APPKEY1 provenance (must be signed by Ledger)
bytes memory LEDGERKEY = hex"7fb956469c5c9b89840d55b43537e66a98dd4811ea0a27224272c2e5622911e8537a2f8e86a46baec82864e98dd01e9ccc2f8bc5dfc9cbe5a91a290498dd96e4";
bytes memory tosign3 = new bytes(1+65);
tosign3[0] = 0xFE;
copyBytes(proof, 3, 65, tosign3, 1);
bytes memory sig3 = new bytes(uint(proof[3+65+1])+2);
copyBytes(proof, 3+65, sig3.length, sig3, 0);
sigok = verifySig(sha256(tosign3), sig3, LEDGERKEY);
return sigok;
}
modifier oraclize_randomDS_proofVerify(bytes32 _queryId, string _result, bytes _proof) {
// Step 1: the prefix has to match 'LP\x01' (Ledger Proof version 1)
require((_proof[0] == "L") && (_proof[1] == "P") && (_proof[2] == 1));
bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName());
require(proofVerified);
_;
}
function oraclize_randomDS_proofVerify__returnCode(bytes32 _queryId, string _result, bytes _proof) internal returns (uint8){
// Step 1: the prefix has to match 'LP\x01' (Ledger Proof version 1)
if ((_proof[0] != "L")||(_proof[1] != "P")||(_proof[2] != 1)) return 1;
bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName());
if (proofVerified == false) return 2;
return 0;
}
function matchBytes32Prefix(bytes32 content, bytes prefix, uint n_random_bytes) internal pure returns (bool){
bool match_ = true;
for (uint256 i=0; i< n_random_bytes; i++) {
if (content[i] != prefix[i]) match_ = false;
}
return match_;
}
function oraclize_randomDS_proofVerify__main(bytes proof, bytes32 queryId, bytes result, string context_name) internal returns (bool){
// Step 2: the unique keyhash has to match with the sha256 of (context name + queryId)
uint ledgerProofLength = 3+65+(uint(proof[3+65+1])+2)+32;
bytes memory keyhash = new bytes(32);
copyBytes(proof, ledgerProofLength, 32, keyhash, 0);
if (!(keccak256(keyhash) == keccak256(sha256(context_name, queryId)))) return false;
bytes memory sig1 = new bytes(uint(proof[ledgerProofLength+(32+8+1+32)+1])+2);
copyBytes(proof, ledgerProofLength+(32+8+1+32), sig1.length, sig1, 0);
// Step 3: we assume sig1 is valid (it will be verified during step 5) and we verify if 'result' is the prefix of sha256(sig1)
if (!matchBytes32Prefix(sha256(sig1), result, uint(proof[ledgerProofLength+32+8]))) return false;
// Step 4: commitment match verification, keccak256(delay, nbytes, unonce, sessionKeyHash) == commitment in storage.
// This is to verify that the computed args match with the ones specified in the query.
bytes memory commitmentSlice1 = new bytes(8+1+32);
copyBytes(proof, ledgerProofLength+32, 8+1+32, commitmentSlice1, 0);
bytes memory sessionPubkey = new bytes(64);
uint sig2offset = ledgerProofLength+32+(8+1+32)+sig1.length+65;
copyBytes(proof, sig2offset-64, 64, sessionPubkey, 0);
bytes32 sessionPubkeyHash = sha256(sessionPubkey);
if (oraclize_randomDS_args[queryId] == keccak256(commitmentSlice1, sessionPubkeyHash)){ //unonce, nbytes and sessionKeyHash match
delete oraclize_randomDS_args[queryId];
} else return false;
// Step 5: validity verification for sig1 (keyhash and args signed with the sessionKey)
bytes memory tosign1 = new bytes(32+8+1+32);
copyBytes(proof, ledgerProofLength, 32+8+1+32, tosign1, 0);
if (!verifySig(sha256(tosign1), sig1, sessionPubkey)) return false;
// verify if sessionPubkeyHash was verified already, if not.. let's do it!
if (oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] == false){
oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] = oraclize_randomDS_proofVerify__sessionKeyValidity(proof, sig2offset);
}
return oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash];
}
// the following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license
function copyBytes(bytes from, uint fromOffset, uint length, bytes to, uint toOffset) internal pure returns (bytes) {
uint minLength = length + toOffset;
// Buffer too small
require(to.length >= minLength); // Should be a better way?
// NOTE: the offset 32 is added to skip the `size` field of both bytes variables
uint i = 32 + fromOffset;
uint j = 32 + toOffset;
while (i < (32 + fromOffset + length)) {
assembly {
let tmp := mload(add(from, i))
mstore(add(to, j), tmp)
}
i += 32;
j += 32;
}
return to;
}
// the following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license
// Duplicate Solidity's ecrecover, but catching the CALL return value
function safer_ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal returns (bool, address) {
// We do our own memory management here. Solidity uses memory offset
// 0x40 to store the current end of memory. We write past it (as
// writes are memory extensions), but don't update the offset so
// Solidity will reuse it. The memory used here is only needed for
// this context.
// FIXME: inline assembly can't access return values
bool ret;
address addr;
assembly {
let size := mload(0x40)
mstore(size, hash)
mstore(add(size, 32), v)
mstore(add(size, 64), r)
mstore(add(size, 96), s)
// NOTE: we can reuse the request memory because we deal with
// the return code
ret := call(3000, 1, 0, size, 128, size, 32)
addr := mload(size)
}
return (ret, addr);
}
// the following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license
function ecrecovery(bytes32 hash, bytes sig) internal returns (bool, address) {
bytes32 r;
bytes32 s;
uint8 v;
if (sig.length != 65)
return (false, 0);
// The signature format is a compact form of:
// {bytes32 r}{bytes32 s}{uint8 v}
// Compact means, uint8 is not padded to 32 bytes.
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
// Here we are loading the last 32 bytes. We exploit the fact that
// 'mload' will pad with zeroes if we overread.
// There is no 'mload8' to do this, but that would be nicer.
v := byte(0, mload(add(sig, 96)))
// Alternative solution:
// 'byte' is not working due to the Solidity parser, so lets
// use the second best option, 'and'
// v := and(mload(add(sig, 65)), 255)
}
// albeit non-transactional signatures are not specified by the YP, one would expect it
// to match the YP range of [27, 28]
//
// geth uses [0, 1] and some clients have followed. This might change, see:
// https://github.com/ethereum/go-ethereum/issues/2053
if (v < 27)
v += 27;
if (v != 27 && v != 28)
return (false, 0);
return safer_ecrecover(hash, v, r, s);
}
}
// </ORACLIZE_API>
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract ERC20 {
uint256 public totalSupply;
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
}
contract StandardToken is ERC20 {
using SafeMath for uint256;
mapping(address => uint256) balances;
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
Transfer(_from, _to, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
/**
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
*/
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
contract FiCoin is StandardToken, usingOraclize {
using SafeMath for uint256;
struct Contributor {
address addr;
uint256 amount;
}
mapping (bytes32 => Contributor) internal contributors;
//==========================================================
// TOKEN PROPERTIES
//==========================================================
string public constant name = "FiCoin";
string public constant symbol = "FiC";
uint256 public constant decimals = 18;
string public version = "1.0";
//==========================================================
// STAGE LIMITS PROPERTIES
//==========================================================
uint256 public saleCap;
//==========================================================
// WALLETS
//==========================================================
address public FiCoinFundDeposit;
address public CoinStorage;
address public OwnerAddress;
//==========================================================
// CROWDSALE STAGES
//==========================================================
bool internal isPreSale = false;
bool internal isFirstRound = false;
bool internal isSecondRound = false;
uint256 public burnedTokens;
//==========================================================
// INTERNAL VARIABLES
//==========================================================
uint256 internal tokenPriceInCents;
uint256 internal buyLimit;
uint256 internal totalLocked;
uint256 internal startDate;
uint256 internal endDate;
mapping(address => uint256) internal lockedTokens;
mapping(address => uint256) internal buyLimitPerAddress;
//==========================================================
// EVENTS
//==========================================================
event OraclizeQuery(string description);
event Burn(address indexed burner, uint256 value);
event TokenPurchase(address indexed purchaser, uint256 value, uint256 amount);
event Lock(address indexed purchaser, uint256 value);
//==========================================================
// MODIFIERS
//==========================================================
modifier onlyOwner() {
require(msg.sender == OwnerAddress);
_;
}
//==========================================================
// CONSTRUCTOR
//==========================================================
function FiCoin() public {
FiCoinFundDeposit = 0x00aa6ddfa8ADD5B1E6bCfFcbaB83c3FDBd10DA91;
CoinStorage = 0x00aD59ec96C12dA4C4546383fac422fEF45a21bB;
OwnerAddress = 0x00aD59ec96C12dA4C4546383fac422fEF45a21bB;
totalSupply = 14930352 * 10 ** decimals;
// crowdsale statistics
tokenPriceInCents = 34;
buyLimit = 0;
saleCap = 0;
// burned tokens
burnedTokens = 0;
// move the supply the storage
balances[CoinStorage] = totalSupply;
startDate = 0;
endDate = 0;
}
//==========================================================
// ONLY OWNER FUNCTIONS
//==========================================================
function forwardFunds() onlyOwner public {
FiCoinFundDeposit.transfer(this.balance);
}
//==========================================================
// PUBLIC FUNCTIONS
//==========================================================
function () public payable {
buyTokens(msg.sender);
}
// low level token purchase function
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(msg.value >= 1 * 10 ** 17); // minimum ETH contribution is 0.1 ETH
require(startDate < now && endDate > now);
// this functionallity is kept in the same function with purpose.
if (oraclize_getPrice("URL") > this.balance) {
OraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
} else {
OraclizeQuery("Oraclize query was sent, standing by for the answer.");
bytes32 queryId = oraclize_query("URL", "json(https://api.coinmarketcap.com/v1/ticker/ethereum).0.price_usd");
contributors[queryId] = Contributor(beneficiary, msg.value);
}
}
function lockedOf(address _owner) public view returns (uint256 locked) {
return lockedTokens[_owner];
}
function __callback(bytes32 myid, string result, bytes proof) public {
require (msg.sender == oraclize_cbAddress());
uint256 etherPrice = parseInt(result, 2);
uint256 purchasedTokens = getPurchasedTokens(contributors[myid].amount, etherPrice);
privateTransfer(contributors[myid].addr, purchasedTokens);
TokenPurchase(contributors[myid].addr, contributors[myid].amount, purchasedTokens);
delete contributors[myid];
}
//==========================================================
// INTERNAL FUNCTIONS
//==========================================================
function getPurchasedTokens(uint256 _weiAmount, uint256 _etherPrice) internal constant returns (uint256) {
require(_etherPrice > 0);
//Formula:
//( weiAmount * etherPrice (cents) ) / ( tokenPrice (cents) )
uint256 purchasedTokens = _weiAmount.mul(_etherPrice);
purchasedTokens = purchasedTokens.div(tokenPriceInCents);
return purchasedTokens;
}
function privateTransfer(address _to, uint256 _value) internal returns (bool) {
require(_to != address(0));
require(_value <= balances[CoinStorage]);
// check that sold tokens + purchase value + totalLocked is less than the saleCap
require(totalSupply - balances[CoinStorage] + _value + totalLocked <= saleCap);
// check that user's locked tokens + purchase value is less than the purchase limit
require(buyLimitPerAddress[_to] + lockedTokens[_to] + _value <= buyLimit);
// SafeMath.sub will throw if there is not enough balance.
balances[CoinStorage] = balances[CoinStorage].sub(_value);
balances[_to] = balances[_to].add(_value);
//===================================================================
buyLimitPerAddress[_to] = buyLimitPerAddress[_to].add(_value);
//===================================================================
Transfer(CoinStorage, _to, _value);
return true;
}
// Add to totalLocked
// Substract from owner's balance
// Init mapping.
function lock(address _to, uint256 _value) onlyOwner public {
require(_to != address(0));
require(_value <= balances[CoinStorage]);
// check that sold tokens + purchase value + totalLocked is less than the saleCap
require(totalSupply - balances[CoinStorage] + _value + totalLocked <= saleCap);
// check that user's locked tokens + purchase value is less than the purchase limit
require(buyLimitPerAddress[_to] + lockedTokens[_to] + _value <= buyLimit);
totalLocked = totalLocked + _value;
balances[CoinStorage] = balances[CoinStorage].sub(_value);
lockedTokens[_to] = _value;
}
// Unlock tokens
// Transfer tokens
function pay(address _to, uint256 _value) onlyOwner public {
unlock(_to);
privateTransfer(_to, _value);
}
// Substract from totalLocked
// Add the locked tokens to the owner's balance
// Delete mapping element
function unlock(address _to) onlyOwner public {
require(_to != address(0));
require(lockedTokens[_to] > 0);
totalLocked = totalLocked.sub(lockedTokens[_to]);
balances[CoinStorage] = balances[CoinStorage].add(lockedTokens[_to]);
delete lockedTokens[_to];
}
//==========================================================
// EXTERNAL FUNCTIONS
//==========================================================
function switchSaleStage() onlyOwner public {
require(!isSecondRound);
if (!isPreSale) {
isPreSale = true;
tokenPriceInCents = 34;
buyLimit = 5000 * 10 ** decimals;
saleCap = 2178309 * 10 ** decimals;
} else if (!isFirstRound) {
isFirstRound = true;
tokenPriceInCents = 55;
buyLimit = buyLimit + 10000 * 10 ** decimals;
saleCap = totalSupply - balances[CoinStorage] + 3524578 * 10 ** decimals;
} else if (!isSecondRound) {
isSecondRound = true;
tokenPriceInCents = 89;
buyLimit = buyLimit + 15000 * 10**decimals;
saleCap = totalSupply - balances[CoinStorage] + 5702887 * 10 ** decimals;
}
startDate = now + 1 minutes;
endDate = startDate + 120 hours;
}
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function burn(uint256 _value) public {
require(_value > 0);
require(_value <= balances[msg.sender]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply = totalSupply.sub(_value);
burnedTokens = burnedTokens.add(_value);
Burn(burner, _value);
}
}File 2 of 3: Oraclize
/*
Copyright (c) 2015-2016 Oraclize SRL
Copyright (c) 2016-2017 Oraclize LTD
*/
/*
Oraclize Connector v1.2.0
*/
// 'compressed' alternative, where all modifiers have been changed to FUNCTIONS
// which is cheaper for deployment, potentially cheaper execution
pragma solidity ^0.4.11;
contract Oraclize {
mapping (address => uint) reqc;
mapping (address => byte) public cbAddresses;
mapping (address => bool) public offchainPayment;
event Log1(address sender, bytes32 cid, uint timestamp, string datasource, string arg, uint gaslimit, byte proofType, uint gasPrice);
event Log2(address sender, bytes32 cid, uint timestamp, string datasource, string arg1, string arg2, uint gaslimit, byte proofType, uint gasPrice);
event LogN(address sender, bytes32 cid, uint timestamp, string datasource, bytes args, uint gaslimit, byte proofType, uint gasPrice);
event Log1_fnc(address sender, bytes32 cid, uint timestamp, string datasource, string arg, function() external callback, uint gaslimit, byte proofType, uint gasPrice);
event Log2_fnc(address sender, bytes32 cid, uint timestamp, string datasource, string arg1, string arg2, function() external callback, uint gaslimit, byte proofType, uint gasPrice);
event LogN_fnc(address sender, bytes32 cid, uint timestamp, string datasource, bytes args, function() external callback, uint gaslimit, byte proofType, uint gasPrice);
event Emit_OffchainPaymentFlag(address indexed idx_sender, address sender, bool indexed idx_flag, bool flag);
address owner;
address paymentFlagger;
function changeAdmin(address _newAdmin)
external
{
onlyadmin();
owner = _newAdmin;
}
function changePaymentFlagger(address _newFlagger)
external
{
onlyadmin();
paymentFlagger = _newFlagger;
}
function addCbAddress(address newCbAddress, byte addressType)
external
{
onlyadmin();
//bytes memory nil = '';
addCbAddress(newCbAddress, addressType, hex'');
}
// proof is currently a placeholder for when associated proof for addressType is added
function addCbAddress(address newCbAddress, byte addressType, bytes proof)
public
{
onlyadmin();
cbAddresses[newCbAddress] = addressType;
}
function removeCbAddress(address newCbAddress)
external
{
onlyadmin();
delete cbAddresses[newCbAddress];
}
function cbAddress()
constant
returns (address _cbAddress)
{
if (cbAddresses[tx.origin] != 0)
_cbAddress = tx.origin;
}
function addDSource(string dsname, uint multiplier)
external
{
addDSource(dsname, 0x00, multiplier);
}
function addDSource(string dsname, byte proofType, uint multiplier)
public
{
onlyadmin();
bytes32 dsname_hash = sha3(dsname, proofType);
dsources[dsources.length++] = dsname_hash;
price_multiplier[dsname_hash] = multiplier;
}
// Utilized by bridge
function multiAddDSource(bytes32[] dsHash, uint256[] multiplier)
external
{
onlyadmin();
// dsHash -> sha3(DATASOURCE_NAME, PROOF_TYPE);
for (uint i=0; i<dsHash.length; i++) {
dsources[dsources.length++] = dsHash[i];
price_multiplier[dsHash[i]] = multiplier[i];
}
}
function multisetProofType(uint[] _proofType, address[] _addr)
external
{
onlyadmin();
for (uint i=0; i<_addr.length; i++) addr_proofType[_addr[i]] = byte(_proofType[i]);
}
function multisetCustomGasPrice(uint[] _gasPrice, address[] _addr)
external
{
onlyadmin();
for (uint i=0; i<_addr.length; i++) addr_gasPrice[_addr[i]] = _gasPrice[i];
}
uint gasprice = 20000000000;
function setGasPrice(uint newgasprice)
external
{
onlyadmin();
gasprice = newgasprice;
}
function setBasePrice(uint new_baseprice)
external
{ //0.001 usd in ether
onlyadmin();
baseprice = new_baseprice;
for (uint i=0; i<dsources.length; i++) price[dsources[i]] = new_baseprice*price_multiplier[dsources[i]];
}
function setBasePrice(uint new_baseprice, bytes proofID)
external
{ //0.001 usd in ether
onlyadmin();
baseprice = new_baseprice;
for (uint i=0; i<dsources.length; i++) price[dsources[i]] = new_baseprice*price_multiplier[dsources[i]];
}
function setOffchainPayment(address _addr, bool _flag)
external
{
if (msg.sender != paymentFlagger) throw;
offchainPayment[_addr] = _flag;
Emit_OffchainPaymentFlag(_addr, _addr, _flag, _flag);
}
function withdrawFunds(address _addr)
external
{
onlyadmin();
_addr.send(this.balance);
}
// unnecessary?
//function() {}
function Oraclize() {
owner = msg.sender;
}
// Pesudo-modifiers
function onlyadmin()
private {
if (msg.sender != owner) throw;
}
function costs(string datasource, uint gaslimit)
private
returns (uint price) {
price = getPrice(datasource, gaslimit, msg.sender);
if (msg.value >= price){
uint diff = msg.value - price;
if (diff > 0) {
// added for correct query cost to be returned
if(!msg.sender.send(diff)) {
throw;
}
}
} else throw;
}
mapping (address => byte) addr_proofType;
mapping (address => uint) addr_gasPrice;
uint public baseprice;
mapping (bytes32 => uint) price;
mapping (bytes32 => uint) price_multiplier;
bytes32[] dsources;
bytes32[] public randomDS_sessionPubKeysHash;
function randomDS_updateSessionPubKeysHash(bytes32[] _newSessionPubKeysHash)
external
{
onlyadmin();
randomDS_sessionPubKeysHash.length = 0;
for (uint i=0; i<_newSessionPubKeysHash.length; i++) randomDS_sessionPubKeysHash.push(_newSessionPubKeysHash[i]);
}
function randomDS_getSessionPubKeyHash()
external
constant
returns (bytes32) {
uint i = uint(sha3(reqc[msg.sender]))%randomDS_sessionPubKeysHash.length;
return randomDS_sessionPubKeysHash[i];
}
function setProofType(byte _proofType)
external
{
addr_proofType[msg.sender] = _proofType;
}
function setCustomGasPrice(uint _gasPrice)
external
{
addr_gasPrice[msg.sender] = _gasPrice;
}
function getPrice(string _datasource)
public
returns (uint _dsprice)
{
return getPrice(_datasource, msg.sender);
}
function getPrice(string _datasource, uint _gaslimit)
public
returns (uint _dsprice)
{
return getPrice(_datasource, _gaslimit, msg.sender);
}
function getPrice(string _datasource, address _addr)
private
returns (uint _dsprice)
{
return getPrice(_datasource, 200000, _addr);
}
function getPrice(string _datasource, uint _gaslimit, address _addr)
private
returns (uint _dsprice)
{
uint gasprice_ = addr_gasPrice[_addr];
if (
(offchainPayment[_addr])
||(
(_gaslimit <= 200000)&&
(reqc[_addr] == 0)&&
(gasprice_ <= gasprice)&&
(tx.origin != cbAddress())
)
) return 0;
if (gasprice_ == 0) gasprice_ = gasprice;
_dsprice = price[sha3(_datasource, addr_proofType[_addr])];
_dsprice += _gaslimit*gasprice_;
return _dsprice;
}
function getCodeSize(address _addr)
private
constant
returns(uint _size)
{
assembly {
_size := extcodesize(_addr)
}
}
function query(string _datasource, string _arg)
payable
external
returns (bytes32 _id)
{
return query1(0, _datasource, _arg, 200000);
}
function query1(string _datasource, string _arg)
payable
external
returns (bytes32 _id)
{
return query1(0, _datasource, _arg, 200000);
}
function query2(string _datasource, string _arg1, string _arg2)
payable
external
returns (bytes32 _id)
{
return query2(0, _datasource, _arg1, _arg2, 200000);
}
function queryN(string _datasource, bytes _args)
payable
external
returns (bytes32 _id)
{
return queryN(0, _datasource, _args, 200000);
}
function query(uint _timestamp, string _datasource, string _arg)
payable
external
returns (bytes32 _id)
{
return query1(_timestamp, _datasource, _arg, 200000);
}
function query1(uint _timestamp, string _datasource, string _arg)
payable
external
returns (bytes32 _id)
{
return query1(_timestamp, _datasource, _arg, 200000);
}
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2)
payable
external
returns (bytes32 _id)
{
return query2(_timestamp, _datasource, _arg1, _arg2, 200000);
}
function queryN(uint _timestamp, string _datasource, bytes _args)
payable
external
returns (bytes32 _id)
{
return queryN(_timestamp, _datasource, _args, 200000);
}
/* Needless?
function query(uint _timestamp, string _datasource, string _arg, uint _gaslimit)
payable
external
returns (bytes32 _id)
{
return query1(_timestamp, _datasource, _arg, _gaslimit);
}
*/
function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit)
payable
external
returns (bytes32 _id)
{
return query1(_timestamp, _datasource, _arg, _gaslimit);
}
function query1_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit)
payable
external
returns (bytes32 _id)
{
return query1(_timestamp, _datasource, _arg, _gaslimit);
}
function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit)
payable
external
returns (bytes32 _id)
{
return query2(_timestamp, _datasource, _arg1, _arg2, _gaslimit);
}
function queryN_withGasLimit(uint _timestamp, string _datasource, bytes _args, uint _gaslimit)
payable
external
returns (bytes32 _id)
{
return queryN(_timestamp, _datasource, _args, _gaslimit);
}
function query1(uint _timestamp, string _datasource, string _arg, uint _gaslimit)
payable
public
returns (bytes32 _id)
{
costs(_datasource, _gaslimit);
if ((_timestamp > now+3600*24*60)||(_gaslimit > block.gaslimit)) throw;
_id = sha3(this, msg.sender, reqc[msg.sender]);
reqc[msg.sender]++;
Log1(msg.sender, _id, _timestamp, _datasource, _arg, _gaslimit, addr_proofType[msg.sender], addr_gasPrice[msg.sender]);
return _id;
}
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit)
payable
public
returns (bytes32 _id)
{
costs(_datasource, _gaslimit);
if ((_timestamp > now+3600*24*60)||(_gaslimit > block.gaslimit)) throw;
_id = sha3(this, msg.sender, reqc[msg.sender]);
reqc[msg.sender]++;
Log2(msg.sender, _id, _timestamp, _datasource, _arg1, _arg2, _gaslimit, addr_proofType[msg.sender], addr_gasPrice[msg.sender]);
return _id;
}
function queryN(uint _timestamp, string _datasource, bytes _args, uint _gaslimit)
payable
public
returns (bytes32 _id)
{
costs(_datasource, _gaslimit);
if ((_timestamp > now+3600*24*60)||(_gaslimit > block.gaslimit)) throw;
_id = sha3(this, msg.sender, reqc[msg.sender]);
reqc[msg.sender]++;
LogN(msg.sender, _id, _timestamp, _datasource, _args, _gaslimit, addr_proofType[msg.sender], addr_gasPrice[msg.sender]);
return _id;
}
function query1_fnc(uint _timestamp, string _datasource, string _arg, function() external _fnc, uint _gaslimit)
payable
public
returns (bytes32 _id)
{
costs(_datasource, _gaslimit);
if ((_timestamp > now+3600*24*60)||(_gaslimit > block.gaslimit)||address(_fnc) != msg.sender) throw;
_id = sha3(this, msg.sender, reqc[msg.sender]);
reqc[msg.sender]++;
Log1_fnc(msg.sender, _id, _timestamp, _datasource, _arg, _fnc, _gaslimit, addr_proofType[msg.sender], addr_gasPrice[msg.sender]);
return _id;
}
function query2_fnc(uint _timestamp, string _datasource, string _arg1, string _arg2, function() external _fnc, uint _gaslimit)
payable
public
returns (bytes32 _id)
{
costs(_datasource, _gaslimit);
if ((_timestamp > now+3600*24*60)||(_gaslimit > block.gaslimit)||address(_fnc) != msg.sender) throw;
_id = sha3(this, msg.sender, reqc[msg.sender]);
reqc[msg.sender]++;
Log2_fnc(msg.sender, _id, _timestamp, _datasource, _arg1, _arg2, _fnc, _gaslimit, addr_proofType[msg.sender], addr_gasPrice[msg.sender]);
return _id;
}
function queryN_fnc(uint _timestamp, string _datasource, bytes _args, function() external _fnc, uint _gaslimit)
payable
public
returns (bytes32 _id)
{
costs(_datasource, _gaslimit);
if ((_timestamp > now+3600*24*60)||(_gaslimit > block.gaslimit)||address(_fnc) != msg.sender) throw;
_id = sha3(this, msg.sender, reqc[msg.sender]);
reqc[msg.sender]++;
LogN_fnc(msg.sender, _id, _timestamp, _datasource, _args, _fnc, _gaslimit, addr_proofType[msg.sender], addr_gasPrice[msg.sender]);
return _id;
}
}File 3 of 3: OraclizeAddrResolver
/*
Copyright (c) 2015-2016 Oraclize SRL
Copyright (c) 2016 Oraclize LTD
*/
contract OraclizeAddrResolver {
address public addr;
address owner;
function OraclizeAddrResolver(){
owner = msg.sender;
}
function changeOwner(address newowner){
if (msg.sender != owner) throw;
owner = newowner;
}
function getAddress() returns (address oaddr){
return addr;
}
function setAddr(address newaddr){
if (msg.sender != owner) throw;
addr = newaddr;
}
}