├── .github └── workflows │ └── manual.yml ├── CODEOWNERS ├── README.md ├── eth-contracts ├── contracts │ ├── ERC721Mintable.sol │ ├── Migrations.sol │ ├── Oraclize.sol │ └── SolnSquareVerifier.sol ├── migrations │ ├── 1_initial_migration.js │ └── 2_deploy_contracts.js ├── test │ ├── TestERC721Mintable.js │ ├── TestSolnSquareVerifier.js │ └── TestSquareVerifier.js └── truffle-config.js ├── package-lock.json ├── package.json └── zokrates └── code └── square └── square.code /.github/workflows/manual.yml: -------------------------------------------------------------------------------- 1 | # Workflow to ensure whenever a Github PR is submitted, 2 | # a JIRA ticket gets created automatically. 3 | name: Manual Workflow 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on pull request events but only for the master branch 8 | pull_request_target: 9 | types: [opened, reopened] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | test-transition-issue: 16 | name: Convert Github Issue to Jira Issue 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@master 21 | 22 | - name: Login 23 | uses: atlassian/gajira-login@master 24 | env: 25 | JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} 26 | JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} 27 | JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} 28 | 29 | - name: Create NEW JIRA ticket 30 | id: create 31 | uses: atlassian/gajira-create@master 32 | with: 33 | project: CONUPDATE 34 | issuetype: Task 35 | summary: | 36 | Github PR [Assign the ND component] | Repo: ${{ github.repository }} | PR# ${{github.event.number}} 37 | description: | 38 | Repo link: https://github.com/${{ github.repository }} 39 | PR no. ${{ github.event.pull_request.number }} 40 | PR title: ${{ github.event.pull_request.title }} 41 | PR description: ${{ github.event.pull_request.description }} 42 | In addition, please resolve other issues, if any. 43 | fields: '{"components": [{"name":"nd013 - Self Driving Car Engineer ND"}], "customfield_16449":"https://classroom.udacity.com/", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' 44 | 45 | - name: Log created issue 46 | run: echo "Issue ${{ steps.create.outputs.issue }} was created" 47 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @udacity/active-public-content -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Udacity Blockchain Capstone 2 | 3 | The capstone will build upon the knowledge you have gained in the course in order to build a decentralized housing product. 4 | 5 | # Project Resources 6 | 7 | * [Remix - Solidity IDE](https://remix.ethereum.org/) 8 | * [Visual Studio Code](https://code.visualstudio.com/) 9 | * [Truffle Framework](https://truffleframework.com/) 10 | * [Ganache - One Click Blockchain](https://truffleframework.com/ganache) 11 | * [Open Zeppelin ](https://openzeppelin.org/) 12 | * [Interactive zero knowledge 3-colorability demonstration](http://web.mit.edu/~ezyang/Public/graph/svg.html) 13 | * [Docker](https://docs.docker.com/install/) 14 | * [ZoKrates](https://github.com/Zokrates/ZoKrates) 15 | -------------------------------------------------------------------------------- /eth-contracts/contracts/ERC721Mintable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | import 'openzeppelin-solidity/contracts/utils/Address.sol'; 4 | import 'openzeppelin-solidity/contracts/drafts/Counters.sol'; 5 | import 'openzeppelin-solidity/contracts/math/SafeMath.sol'; 6 | import 'openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol'; 7 | import "./Oraclize.sol"; 8 | 9 | contract Ownable { 10 | // TODO's 11 | // 1) create a private '_owner' variable of type address with a public getter function 12 | // 2) create an internal constructor that sets the _owner var to the creater of the contract 13 | // 3) create an 'onlyOwner' modifier that throws if called by any account other than the owner. 14 | // 4) fill out the transferOwnership function 15 | // 5) create an event that emits anytime ownerShip is transfered (including in the constructor) 16 | 17 | function transferOwnership(address newOwner) public onlyOwner { 18 | // TODO add functionality to transfer control of the contract to a newOwner. 19 | // make sure the new owner is a real address 20 | 21 | } 22 | } 23 | 24 | // TODO's: Create a Pausable contract that inherits from the Ownable contract 25 | // 1) create a private '_paused' variable of type bool 26 | // 2) create a public setter using the inherited onlyOwner modifier 27 | // 3) create an internal constructor that sets the _paused variable to false 28 | // 4) create 'whenNotPaused' & 'paused' modifier that throws in the appropriate situation 29 | // 5) create a Paused & Unpaused event that emits the address that triggered the event 30 | 31 | contract ERC165 { 32 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 33 | /* 34 | * 0x01ffc9a7 === 35 | * bytes4(keccak256('supportsInterface(bytes4)')) 36 | */ 37 | 38 | /** 39 | * @dev a mapping of interface id to whether or not it's supported 40 | */ 41 | mapping(bytes4 => bool) private _supportedInterfaces; 42 | 43 | /** 44 | * @dev A contract implementing SupportsInterfaceWithLookup 45 | * implement ERC165 itself 46 | */ 47 | constructor () internal { 48 | _registerInterface(_INTERFACE_ID_ERC165); 49 | } 50 | 51 | /** 52 | * @dev implement supportsInterface(bytes4) using a lookup table 53 | */ 54 | function supportsInterface(bytes4 interfaceId) external view returns (bool) { 55 | return _supportedInterfaces[interfaceId]; 56 | } 57 | 58 | /** 59 | * @dev internal method for registering an interface 60 | */ 61 | function _registerInterface(bytes4 interfaceId) internal { 62 | require(interfaceId != 0xffffffff); 63 | _supportedInterfaces[interfaceId] = true; 64 | } 65 | } 66 | 67 | contract ERC721 is Pausable, ERC165 { 68 | 69 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); 70 | 71 | event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); 72 | 73 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved); 74 | 75 | using SafeMath for uint256; 76 | using Address for address; 77 | using Counters for Counters.Counter; 78 | 79 | // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` 80 | // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` 81 | bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; 82 | 83 | // Mapping from token ID to owner 84 | mapping (uint256 => address) private _tokenOwner; 85 | 86 | // Mapping from token ID to approved address 87 | mapping (uint256 => address) private _tokenApprovals; 88 | 89 | // Mapping from owner to number of owned token 90 | // IMPORTANT: this mapping uses Counters lib which is used to protect overflow when incrementing/decrementing a uint 91 | // use the following functions when interacting with Counters: increment(), decrement(), and current() to get the value 92 | // see: https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/drafts/Counters.sol 93 | mapping (address => Counters.Counter) private _ownedTokensCount; 94 | 95 | // Mapping from owner to operator approvals 96 | mapping (address => mapping (address => bool)) private _operatorApprovals; 97 | 98 | bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; 99 | 100 | constructor () public { 101 | // register the supported interfaces to conform to ERC721 via ERC165 102 | _registerInterface(_INTERFACE_ID_ERC721); 103 | } 104 | 105 | function balanceOf(address owner) public view returns (uint256) { 106 | // TODO return the token balance of given address 107 | // TIP: remember the functions to use for Counters. you can refresh yourself with the link above 108 | } 109 | 110 | function ownerOf(uint256 tokenId) public view returns (address) { 111 | // TODO return the owner of the given tokenId 112 | } 113 | 114 | // @dev Approves another address to transfer the given token ID 115 | function approve(address to, uint256 tokenId) public { 116 | 117 | // TODO require the given address to not be the owner of the tokenId 118 | 119 | // TODO require the msg sender to be the owner of the contract or isApprovedForAll() to be true 120 | 121 | // TODO add 'to' address to token approvals 122 | 123 | // TODO emit Approval Event 124 | 125 | } 126 | 127 | function getApproved(uint256 tokenId) public view returns (address) { 128 | // TODO return token approval if it exists 129 | } 130 | 131 | /** 132 | * @dev Sets or unsets the approval of a given operator 133 | * An operator is allowed to transfer all tokens of the sender on their behalf 134 | * @param to operator address to set the approval 135 | * @param approved representing the status of the approval to be set 136 | */ 137 | function setApprovalForAll(address to, bool approved) public { 138 | require(to != msg.sender); 139 | _operatorApprovals[msg.sender][to] = approved; 140 | emit ApprovalForAll(msg.sender, to, approved); 141 | } 142 | 143 | /** 144 | * @dev Tells whether an operator is approved by a given owner 145 | * @param owner owner address which you want to query the approval of 146 | * @param operator operator address which you want to query the approval of 147 | * @return bool whether the given operator is approved by the given owner 148 | */ 149 | function isApprovedForAll(address owner, address operator) public view returns (bool) { 150 | return _operatorApprovals[owner][operator]; 151 | } 152 | 153 | function transferFrom(address from, address to, uint256 tokenId) public { 154 | require(_isApprovedOrOwner(msg.sender, tokenId)); 155 | 156 | _transferFrom(from, to, tokenId); 157 | } 158 | 159 | function safeTransferFrom(address from, address to, uint256 tokenId) public { 160 | safeTransferFrom(from, to, tokenId, ""); 161 | } 162 | 163 | function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { 164 | transferFrom(from, to, tokenId); 165 | require(_checkOnERC721Received(from, to, tokenId, _data)); 166 | } 167 | 168 | /** 169 | * @dev Returns whether the specified token exists 170 | * @param tokenId uint256 ID of the token to query the existence of 171 | * @return bool whether the token exists 172 | */ 173 | function _exists(uint256 tokenId) internal view returns (bool) { 174 | address owner = _tokenOwner[tokenId]; 175 | return owner != address(0); 176 | } 177 | 178 | /** 179 | * @dev Returns whether the given spender can transfer a given token ID 180 | * @param spender address of the spender to query 181 | * @param tokenId uint256 ID of the token to be transferred 182 | * @return bool whether the msg.sender is approved for the given token ID, 183 | * is an operator of the owner, or is the owner of the token 184 | */ 185 | function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { 186 | address owner = ownerOf(tokenId); 187 | return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); 188 | } 189 | 190 | // @dev Internal function to mint a new token 191 | // TIP: remember the functions to use for Counters. you can refresh yourself with the link above 192 | function _mint(address to, uint256 tokenId) internal { 193 | 194 | // TODO revert if given tokenId already exists or given address is invalid 195 | 196 | // TODO mint tokenId to given address & increase token count of owner 197 | 198 | // TODO emit Transfer event 199 | } 200 | 201 | // @dev Internal function to transfer ownership of a given token ID to another address. 202 | // TIP: remember the functions to use for Counters. you can refresh yourself with the link above 203 | function _transferFrom(address from, address to, uint256 tokenId) internal { 204 | 205 | // TODO: require from address is the owner of the given token 206 | 207 | // TODO: require token is being transfered to valid address 208 | 209 | // TODO: clear approval 210 | 211 | // TODO: update token counts & transfer ownership of the token ID 212 | 213 | // TODO: emit correct event 214 | } 215 | 216 | /** 217 | * @dev Internal function to invoke `onERC721Received` on a target address 218 | * The call is not executed if the target address is not a contract 219 | * @param from address representing the previous owner of the given token ID 220 | * @param to target address that will receive the tokens 221 | * @param tokenId uint256 ID of the token to be transferred 222 | * @param _data bytes optional data to send along with the call 223 | * @return bool whether the call correctly returned the expected magic value 224 | */ 225 | function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) 226 | internal returns (bool) 227 | { 228 | if (!to.isContract()) { 229 | return true; 230 | } 231 | 232 | bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); 233 | return (retval == _ERC721_RECEIVED); 234 | } 235 | 236 | // @dev Private function to clear current approval of a given token ID 237 | function _clearApproval(uint256 tokenId) private { 238 | if (_tokenApprovals[tokenId] != address(0)) { 239 | _tokenApprovals[tokenId] = address(0); 240 | } 241 | } 242 | } 243 | 244 | contract ERC721Enumerable is ERC165, ERC721 { 245 | // Mapping from owner to list of owned token IDs 246 | mapping(address => uint256[]) private _ownedTokens; 247 | 248 | // Mapping from token ID to index of the owner tokens list 249 | mapping(uint256 => uint256) private _ownedTokensIndex; 250 | 251 | // Array with all token ids, used for enumeration 252 | uint256[] private _allTokens; 253 | 254 | // Mapping from token id to position in the allTokens array 255 | mapping(uint256 => uint256) private _allTokensIndex; 256 | 257 | bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; 258 | /* 259 | * 0x780e9d63 === 260 | * bytes4(keccak256('totalSupply()')) ^ 261 | * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ 262 | * bytes4(keccak256('tokenByIndex(uint256)')) 263 | */ 264 | 265 | /** 266 | * @dev Constructor function 267 | */ 268 | constructor () public { 269 | // register the supported interface to conform to ERC721Enumerable via ERC165 270 | _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); 271 | } 272 | 273 | /** 274 | * @dev Gets the token ID at a given index of the tokens list of the requested owner 275 | * @param owner address owning the tokens list to be accessed 276 | * @param index uint256 representing the index to be accessed of the requested tokens list 277 | * @return uint256 token ID at the given index of the tokens list owned by the requested address 278 | */ 279 | function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) { 280 | require(index < balanceOf(owner)); 281 | return _ownedTokens[owner][index]; 282 | } 283 | 284 | /** 285 | * @dev Gets the total amount of tokens stored by the contract 286 | * @return uint256 representing the total amount of tokens 287 | */ 288 | function totalSupply() public view returns (uint256) { 289 | return _allTokens.length; 290 | } 291 | 292 | /** 293 | * @dev Gets the token ID at a given index of all the tokens in this contract 294 | * Reverts if the index is greater or equal to the total number of tokens 295 | * @param index uint256 representing the index to be accessed of the tokens list 296 | * @return uint256 token ID at the given index of the tokens list 297 | */ 298 | function tokenByIndex(uint256 index) public view returns (uint256) { 299 | require(index < totalSupply()); 300 | return _allTokens[index]; 301 | } 302 | 303 | /** 304 | * @dev Internal function to transfer ownership of a given token ID to another address. 305 | * As opposed to transferFrom, this imposes no restrictions on msg.sender. 306 | * @param from current owner of the token 307 | * @param to address to receive the ownership of the given token ID 308 | * @param tokenId uint256 ID of the token to be transferred 309 | */ 310 | function _transferFrom(address from, address to, uint256 tokenId) internal { 311 | super._transferFrom(from, to, tokenId); 312 | 313 | _removeTokenFromOwnerEnumeration(from, tokenId); 314 | 315 | _addTokenToOwnerEnumeration(to, tokenId); 316 | } 317 | 318 | /** 319 | * @dev Internal function to mint a new token 320 | * Reverts if the given token ID already exists 321 | * @param to address the beneficiary that will own the minted token 322 | * @param tokenId uint256 ID of the token to be minted 323 | */ 324 | function _mint(address to, uint256 tokenId) internal { 325 | super._mint(to, tokenId); 326 | 327 | _addTokenToOwnerEnumeration(to, tokenId); 328 | 329 | _addTokenToAllTokensEnumeration(tokenId); 330 | } 331 | 332 | /** 333 | * @dev Gets the list of token IDs of the requested owner 334 | * @param owner address owning the tokens 335 | * @return uint256[] List of token IDs owned by the requested address 336 | */ 337 | function _tokensOfOwner(address owner) internal view returns (uint256[] storage) { 338 | return _ownedTokens[owner]; 339 | } 340 | 341 | /** 342 | * @dev Private function to add a token to this extension's ownership-tracking data structures. 343 | * @param to address representing the new owner of the given token ID 344 | * @param tokenId uint256 ID of the token to be added to the tokens list of the given address 345 | */ 346 | function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { 347 | _ownedTokensIndex[tokenId] = _ownedTokens[to].length; 348 | _ownedTokens[to].push(tokenId); 349 | } 350 | 351 | /** 352 | * @dev Private function to add a token to this extension's token tracking data structures. 353 | * @param tokenId uint256 ID of the token to be added to the tokens list 354 | */ 355 | function _addTokenToAllTokensEnumeration(uint256 tokenId) private { 356 | _allTokensIndex[tokenId] = _allTokens.length; 357 | _allTokens.push(tokenId); 358 | } 359 | 360 | /** 361 | * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that 362 | * while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for 363 | * gas optimizations e.g. when performing a transfer operation (avoiding double writes). 364 | * This has O(1) time complexity, but alters the order of the _ownedTokens array. 365 | * @param from address representing the previous owner of the given token ID 366 | * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address 367 | */ 368 | function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { 369 | // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and 370 | // then delete the last slot (swap and pop). 371 | 372 | uint256 lastTokenIndex = _ownedTokens[from].length.sub(1); 373 | uint256 tokenIndex = _ownedTokensIndex[tokenId]; 374 | 375 | // When the token to delete is the last token, the swap operation is unnecessary 376 | if (tokenIndex != lastTokenIndex) { 377 | uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; 378 | 379 | _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token 380 | _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index 381 | } 382 | 383 | // This also deletes the contents at the last position of the array 384 | _ownedTokens[from].length--; 385 | 386 | // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by 387 | // lastTokenId, or just over the end of the array if the token was the last one). 388 | } 389 | 390 | /** 391 | * @dev Private function to remove a token from this extension's token tracking data structures. 392 | * This has O(1) time complexity, but alters the order of the _allTokens array. 393 | * @param tokenId uint256 ID of the token to be removed from the tokens list 394 | */ 395 | function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { 396 | // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and 397 | // then delete the last slot (swap and pop). 398 | 399 | uint256 lastTokenIndex = _allTokens.length.sub(1); 400 | uint256 tokenIndex = _allTokensIndex[tokenId]; 401 | 402 | // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so 403 | // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding 404 | // an 'if' statement (like in _removeTokenFromOwnerEnumeration) 405 | uint256 lastTokenId = _allTokens[lastTokenIndex]; 406 | 407 | _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token 408 | _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index 409 | 410 | // This also deletes the contents at the last position of the array 411 | _allTokens.length--; 412 | _allTokensIndex[tokenId] = 0; 413 | } 414 | } 415 | 416 | contract ERC721Metadata is ERC721Enumerable, usingOraclize { 417 | 418 | // TODO: Create private vars for token _name, _symbol, and _baseTokenURI (string) 419 | 420 | // TODO: create private mapping of tokenId's to token uri's called '_tokenURIs' 421 | 422 | bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; 423 | /* 424 | * 0x5b5e139f === 425 | * bytes4(keccak256('name()')) ^ 426 | * bytes4(keccak256('symbol()')) ^ 427 | * bytes4(keccak256('tokenURI(uint256)')) 428 | */ 429 | 430 | 431 | constructor (string memory name, string memory symbol, string memory baseTokenURI) public { 432 | // TODO: set instance var values 433 | 434 | _registerInterface(_INTERFACE_ID_ERC721_METADATA); 435 | } 436 | 437 | // TODO: create external getter functions for name, symbol, and baseTokenURI 438 | 439 | function tokenURI(uint256 tokenId) external view returns (string memory) { 440 | require(_exists(tokenId)); 441 | return _tokenURIs[tokenId]; 442 | } 443 | 444 | 445 | // TODO: Create an internal function to set the tokenURI of a specified tokenId 446 | // It should be the _baseTokenURI + the tokenId in string form 447 | // TIP #1: use strConcat() from the imported oraclizeAPI lib to set the complete token URI 448 | // TIP #2: you can also use uint2str() to convert a uint to a string 449 | // see https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol for strConcat() 450 | // require the token exists before setting 451 | 452 | } 453 | 454 | // TODO's: Create CustomERC721Token contract that inherits from the ERC721Metadata contract. You can name this contract as you please 455 | // 1) Pass in appropriate values for the inherited ERC721Metadata contract 456 | // - make the base token uri: https://s3-us-west-2.amazonaws.com/udacity-blockchain/capstone/ 457 | // 2) create a public mint() that does the following: 458 | // -can only be executed by the contract owner 459 | // -takes in a 'to' address, tokenId, and tokenURI as parameters 460 | // -returns a true boolean upon completion of the function 461 | // -calls the superclass mint and setTokenURI functions 462 | 463 | 464 | 465 | -------------------------------------------------------------------------------- /eth-contracts/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.6.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /eth-contracts/contracts/Oraclize.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ORACLIZE_API 4 | 5 | Copyright (c) 2015-2016 Oraclize SRL 6 | Copyright (c) 2016 Oraclize LTD 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | */ 27 | pragma solidity >= 0.5.0; // Incompatible compiler version - please select a compiler within the stated pragma range, or use a different version of the oraclizeAPI! 28 | 29 | // Dummy contract only used to emit to end-user they are using wrong solc 30 | contract solcChecker { 31 | /* INCOMPATIBLE SOLC: import the following instead: "github.com/oraclize/ethereum-api/oraclizeAPI_0.4.sol" */ function f(bytes calldata x) external; 32 | } 33 | 34 | contract OraclizeI { 35 | 36 | address public cbAddress; 37 | 38 | function setProofType(byte _proofType) external; 39 | function setCustomGasPrice(uint _gasPrice) external; 40 | function getPrice(string memory _datasource) public returns (uint _dsprice); 41 | function randomDS_getSessionPubKeyHash() external view returns (bytes32 _sessionKeyHash); 42 | function getPrice(string memory _datasource, uint _gasLimit) public returns (uint _dsprice); 43 | function queryN(uint _timestamp, string memory _datasource, bytes memory _argN) public payable returns (bytes32 _id); 44 | function query(uint _timestamp, string calldata _datasource, string calldata _arg) external payable returns (bytes32 _id); 45 | function query2(uint _timestamp, string memory _datasource, string memory _arg1, string memory _arg2) public payable returns (bytes32 _id); 46 | function query_withGasLimit(uint _timestamp, string calldata _datasource, string calldata _arg, uint _gasLimit) external payable returns (bytes32 _id); 47 | function queryN_withGasLimit(uint _timestamp, string calldata _datasource, bytes calldata _argN, uint _gasLimit) external payable returns (bytes32 _id); 48 | function query2_withGasLimit(uint _timestamp, string calldata _datasource, string calldata _arg1, string calldata _arg2, uint _gasLimit) external payable returns (bytes32 _id); 49 | } 50 | 51 | contract OraclizeAddrResolverI { 52 | function getAddress() public returns (address _address); 53 | } 54 | /* 55 | 56 | Begin solidity-cborutils 57 | 58 | https://github.com/smartcontractkit/solidity-cborutils 59 | 60 | MIT License 61 | 62 | Copyright (c) 2018 SmartContract ChainLink, Ltd. 63 | 64 | Permission is hereby granted, free of charge, to any person obtaining a copy 65 | of this software and associated documentation files (the "Software"), to deal 66 | in the Software without restriction, including without limitation the rights 67 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 68 | copies of the Software, and to permit persons to whom the Software is 69 | furnished to do so, subject to the following conditions: 70 | 71 | The above copyright notice and this permission notice shall be included in all 72 | copies or substantial portions of the Software. 73 | 74 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 75 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 76 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 77 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 78 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 79 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 80 | SOFTWARE. 81 | 82 | */ 83 | library Buffer { 84 | 85 | struct buffer { 86 | bytes buf; 87 | uint capacity; 88 | } 89 | 90 | function init(buffer memory _buf, uint _capacity) internal pure { 91 | uint capacity = _capacity; 92 | if (capacity % 32 != 0) { 93 | capacity += 32 - (capacity % 32); 94 | } 95 | _buf.capacity = capacity; // Allocate space for the buffer data 96 | assembly { 97 | let ptr := mload(0x40) 98 | mstore(_buf, ptr) 99 | mstore(ptr, 0) 100 | mstore(0x40, add(ptr, capacity)) 101 | } 102 | } 103 | 104 | function resize(buffer memory _buf, uint _capacity) private pure { 105 | bytes memory oldbuf = _buf.buf; 106 | init(_buf, _capacity); 107 | append(_buf, oldbuf); 108 | } 109 | 110 | function max(uint _a, uint _b) private pure returns (uint _max) { 111 | if (_a > _b) { 112 | return _a; 113 | } 114 | return _b; 115 | } 116 | /** 117 | * @dev Appends a byte array to the end of the buffer. Resizes if doing so 118 | * would exceed the capacity of the buffer. 119 | * @param _buf The buffer to append to. 120 | * @param _data The data to append. 121 | * @return The original buffer. 122 | * 123 | */ 124 | function append(buffer memory _buf, bytes memory _data) internal pure returns (buffer memory _buffer) { 125 | if (_data.length + _buf.buf.length > _buf.capacity) { 126 | resize(_buf, max(_buf.capacity, _data.length) * 2); 127 | } 128 | uint dest; 129 | uint src; 130 | uint len = _data.length; 131 | assembly { 132 | let bufptr := mload(_buf) // Memory address of the buffer data 133 | let buflen := mload(bufptr) // Length of existing buffer data 134 | dest := add(add(bufptr, buflen), 32) // Start address = buffer address + buffer length + sizeof(buffer length) 135 | mstore(bufptr, add(buflen, mload(_data))) // Update buffer length 136 | src := add(_data, 32) 137 | } 138 | for(; len >= 32; len -= 32) { // Copy word-length chunks while possible 139 | assembly { 140 | mstore(dest, mload(src)) 141 | } 142 | dest += 32; 143 | src += 32; 144 | } 145 | uint mask = 256 ** (32 - len) - 1; // Copy remaining bytes 146 | assembly { 147 | let srcpart := and(mload(src), not(mask)) 148 | let destpart := and(mload(dest), mask) 149 | mstore(dest, or(destpart, srcpart)) 150 | } 151 | return _buf; 152 | } 153 | /** 154 | * 155 | * @dev Appends a byte to the end of the buffer. Resizes if doing so would 156 | * exceed the capacity of the buffer. 157 | * @param _buf The buffer to append to. 158 | * @param _data The data to append. 159 | * @return The original buffer. 160 | * 161 | */ 162 | function append(buffer memory _buf, uint8 _data) internal pure { 163 | if (_buf.buf.length + 1 > _buf.capacity) { 164 | resize(_buf, _buf.capacity * 2); 165 | } 166 | assembly { 167 | let bufptr := mload(_buf) // Memory address of the buffer data 168 | let buflen := mload(bufptr) // Length of existing buffer data 169 | let dest := add(add(bufptr, buflen), 32) // Address = buffer address + buffer length + sizeof(buffer length) 170 | mstore8(dest, _data) 171 | mstore(bufptr, add(buflen, 1)) // Update buffer length 172 | } 173 | } 174 | /** 175 | * 176 | * @dev Appends a byte to the end of the buffer. Resizes if doing so would 177 | * exceed the capacity of the buffer. 178 | * @param _buf The buffer to append to. 179 | * @param _data The data to append. 180 | * @return The original buffer. 181 | * 182 | */ 183 | function appendInt(buffer memory _buf, uint _data, uint _len) internal pure returns (buffer memory _buffer) { 184 | if (_len + _buf.buf.length > _buf.capacity) { 185 | resize(_buf, max(_buf.capacity, _len) * 2); 186 | } 187 | uint mask = 256 ** _len - 1; 188 | assembly { 189 | let bufptr := mload(_buf) // Memory address of the buffer data 190 | let buflen := mload(bufptr) // Length of existing buffer data 191 | let dest := add(add(bufptr, buflen), _len) // Address = buffer address + buffer length + sizeof(buffer length) + len 192 | mstore(dest, or(and(mload(dest), not(mask)), _data)) 193 | mstore(bufptr, add(buflen, _len)) // Update buffer length 194 | } 195 | return _buf; 196 | } 197 | } 198 | 199 | library CBOR { 200 | 201 | using Buffer for Buffer.buffer; 202 | 203 | uint8 private constant MAJOR_TYPE_INT = 0; 204 | uint8 private constant MAJOR_TYPE_MAP = 5; 205 | uint8 private constant MAJOR_TYPE_BYTES = 2; 206 | uint8 private constant MAJOR_TYPE_ARRAY = 4; 207 | uint8 private constant MAJOR_TYPE_STRING = 3; 208 | uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1; 209 | uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7; 210 | 211 | function encodeType(Buffer.buffer memory _buf, uint8 _major, uint _value) private pure { 212 | if (_value <= 23) { 213 | _buf.append(uint8((_major << 5) | _value)); 214 | } else if (_value <= 0xFF) { 215 | _buf.append(uint8((_major << 5) | 24)); 216 | _buf.appendInt(_value, 1); 217 | } else if (_value <= 0xFFFF) { 218 | _buf.append(uint8((_major << 5) | 25)); 219 | _buf.appendInt(_value, 2); 220 | } else if (_value <= 0xFFFFFFFF) { 221 | _buf.append(uint8((_major << 5) | 26)); 222 | _buf.appendInt(_value, 4); 223 | } else if (_value <= 0xFFFFFFFFFFFFFFFF) { 224 | _buf.append(uint8((_major << 5) | 27)); 225 | _buf.appendInt(_value, 8); 226 | } 227 | } 228 | 229 | function encodeIndefiniteLengthType(Buffer.buffer memory _buf, uint8 _major) private pure { 230 | _buf.append(uint8((_major << 5) | 31)); 231 | } 232 | 233 | function encodeUInt(Buffer.buffer memory _buf, uint _value) internal pure { 234 | encodeType(_buf, MAJOR_TYPE_INT, _value); 235 | } 236 | 237 | function encodeInt(Buffer.buffer memory _buf, int _value) internal pure { 238 | if (_value >= 0) { 239 | encodeType(_buf, MAJOR_TYPE_INT, uint(_value)); 240 | } else { 241 | encodeType(_buf, MAJOR_TYPE_NEGATIVE_INT, uint(-1 - _value)); 242 | } 243 | } 244 | 245 | function encodeBytes(Buffer.buffer memory _buf, bytes memory _value) internal pure { 246 | encodeType(_buf, MAJOR_TYPE_BYTES, _value.length); 247 | _buf.append(_value); 248 | } 249 | 250 | function encodeString(Buffer.buffer memory _buf, string memory _value) internal pure { 251 | encodeType(_buf, MAJOR_TYPE_STRING, bytes(_value).length); 252 | _buf.append(bytes(_value)); 253 | } 254 | 255 | function startArray(Buffer.buffer memory _buf) internal pure { 256 | encodeIndefiniteLengthType(_buf, MAJOR_TYPE_ARRAY); 257 | } 258 | 259 | function startMap(Buffer.buffer memory _buf) internal pure { 260 | encodeIndefiniteLengthType(_buf, MAJOR_TYPE_MAP); 261 | } 262 | 263 | function endSequence(Buffer.buffer memory _buf) internal pure { 264 | encodeIndefiniteLengthType(_buf, MAJOR_TYPE_CONTENT_FREE); 265 | } 266 | } 267 | /* 268 | 269 | End solidity-cborutils 270 | 271 | */ 272 | contract usingOraclize { 273 | 274 | using CBOR for Buffer.buffer; 275 | 276 | OraclizeI oraclize; 277 | OraclizeAddrResolverI OAR; 278 | 279 | uint constant day = 60 * 60 * 24; 280 | uint constant week = 60 * 60 * 24 * 7; 281 | uint constant month = 60 * 60 * 24 * 30; 282 | 283 | byte constant proofType_NONE = 0x00; 284 | byte constant proofType_Ledger = 0x30; 285 | byte constant proofType_Native = 0xF0; 286 | byte constant proofStorage_IPFS = 0x01; 287 | byte constant proofType_Android = 0x40; 288 | byte constant proofType_TLSNotary = 0x10; 289 | 290 | string oraclize_network_name; 291 | uint8 constant networkID_auto = 0; 292 | uint8 constant networkID_morden = 2; 293 | uint8 constant networkID_mainnet = 1; 294 | uint8 constant networkID_testnet = 2; 295 | uint8 constant networkID_consensys = 161; 296 | 297 | mapping(bytes32 => bytes32) oraclize_randomDS_args; 298 | mapping(bytes32 => bool) oraclize_randomDS_sessionKeysHashVerified; 299 | 300 | modifier oraclizeAPI { 301 | if ((address(OAR) == address(0)) || (getCodeSize(address(OAR)) == 0)) { 302 | oraclize_setNetwork(networkID_auto); 303 | } 304 | if (address(oraclize) != OAR.getAddress()) { 305 | oraclize = OraclizeI(OAR.getAddress()); 306 | } 307 | _; 308 | } 309 | 310 | modifier oraclize_randomDS_proofVerify(bytes32 _queryId, string memory _result, bytes memory _proof) { 311 | // RandomDS Proof Step 1: The prefix has to match 'LP\x01' (Ledger Proof version 1) 312 | require((_proof[0] == "L") && (_proof[1] == "P") && (uint8(_proof[2]) == uint8(1))); 313 | bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName()); 314 | require(proofVerified); 315 | _; 316 | } 317 | 318 | function oraclize_setNetwork(uint8 _networkID) internal returns (bool _networkSet) { 319 | return oraclize_setNetwork(); 320 | _networkID; // silence the warning and remain backwards compatible 321 | } 322 | 323 | function oraclize_setNetworkName(string memory _network_name) internal { 324 | oraclize_network_name = _network_name; 325 | } 326 | 327 | function oraclize_getNetworkName() internal view returns (string memory _networkName) { 328 | return oraclize_network_name; 329 | } 330 | 331 | function oraclize_setNetwork() internal returns (bool _networkSet) { 332 | if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed) > 0) { //mainnet 333 | OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed); 334 | oraclize_setNetworkName("eth_mainnet"); 335 | return true; 336 | } 337 | if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1) > 0) { //ropsten testnet 338 | OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1); 339 | oraclize_setNetworkName("eth_ropsten3"); 340 | return true; 341 | } 342 | if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e) > 0) { //kovan testnet 343 | OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e); 344 | oraclize_setNetworkName("eth_kovan"); 345 | return true; 346 | } 347 | if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48) > 0) { //rinkeby testnet 348 | OAR = OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48); 349 | oraclize_setNetworkName("eth_rinkeby"); 350 | return true; 351 | } 352 | if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475) > 0) { //ethereum-bridge 353 | OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475); 354 | return true; 355 | } 356 | if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF) > 0) { //ether.camp ide 357 | OAR = OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF); 358 | return true; 359 | } 360 | if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA) > 0) { //browser-solidity 361 | OAR = OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA); 362 | return true; 363 | } 364 | return false; 365 | } 366 | 367 | function __callback(bytes32 _myid, string memory _result) public { 368 | __callback(_myid, _result, new bytes(0)); 369 | } 370 | 371 | function __callback(bytes32 _myid, string memory _result, bytes memory _proof) public { 372 | return; 373 | _myid; _result; _proof; // Silence compiler warnings 374 | } 375 | 376 | function oraclize_getPrice(string memory _datasource) oraclizeAPI internal returns (uint _queryPrice) { 377 | return oraclize.getPrice(_datasource); 378 | } 379 | 380 | function oraclize_getPrice(string memory _datasource, uint _gasLimit) oraclizeAPI internal returns (uint _queryPrice) { 381 | return oraclize.getPrice(_datasource, _gasLimit); 382 | } 383 | 384 | function oraclize_query(string memory _datasource, string memory _arg) oraclizeAPI internal returns (bytes32 _id) { 385 | uint price = oraclize.getPrice(_datasource); 386 | if (price > 1 ether + tx.gasprice * 200000) { 387 | return 0; // Unexpectedly high price 388 | } 389 | return oraclize.query.value(price)(0, _datasource, _arg); 390 | } 391 | 392 | function oraclize_query(uint _timestamp, string memory _datasource, string memory _arg) oraclizeAPI internal returns (bytes32 _id) { 393 | uint price = oraclize.getPrice(_datasource); 394 | if (price > 1 ether + tx.gasprice * 200000) { 395 | return 0; // Unexpectedly high price 396 | } 397 | return oraclize.query.value(price)(_timestamp, _datasource, _arg); 398 | } 399 | 400 | function oraclize_query(uint _timestamp, string memory _datasource, string memory _arg, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 401 | uint price = oraclize.getPrice(_datasource,_gasLimit); 402 | if (price > 1 ether + tx.gasprice * _gasLimit) { 403 | return 0; // Unexpectedly high price 404 | } 405 | return oraclize.query_withGasLimit.value(price)(_timestamp, _datasource, _arg, _gasLimit); 406 | } 407 | 408 | function oraclize_query(string memory _datasource, string memory _arg, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 409 | uint price = oraclize.getPrice(_datasource, _gasLimit); 410 | if (price > 1 ether + tx.gasprice * _gasLimit) { 411 | return 0; // Unexpectedly high price 412 | } 413 | return oraclize.query_withGasLimit.value(price)(0, _datasource, _arg, _gasLimit); 414 | } 415 | 416 | function oraclize_query(string memory _datasource, string memory _arg1, string memory _arg2) oraclizeAPI internal returns (bytes32 _id) { 417 | uint price = oraclize.getPrice(_datasource); 418 | if (price > 1 ether + tx.gasprice * 200000) { 419 | return 0; // Unexpectedly high price 420 | } 421 | return oraclize.query2.value(price)(0, _datasource, _arg1, _arg2); 422 | } 423 | 424 | function oraclize_query(uint _timestamp, string memory _datasource, string memory _arg1, string memory _arg2) oraclizeAPI internal returns (bytes32 _id) { 425 | uint price = oraclize.getPrice(_datasource); 426 | if (price > 1 ether + tx.gasprice * 200000) { 427 | return 0; // Unexpectedly high price 428 | } 429 | return oraclize.query2.value(price)(_timestamp, _datasource, _arg1, _arg2); 430 | } 431 | 432 | function oraclize_query(uint _timestamp, string memory _datasource, string memory _arg1, string memory _arg2, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 433 | uint price = oraclize.getPrice(_datasource, _gasLimit); 434 | if (price > 1 ether + tx.gasprice * _gasLimit) { 435 | return 0; // Unexpectedly high price 436 | } 437 | return oraclize.query2_withGasLimit.value(price)(_timestamp, _datasource, _arg1, _arg2, _gasLimit); 438 | } 439 | 440 | function oraclize_query(string memory _datasource, string memory _arg1, string memory _arg2, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 441 | uint price = oraclize.getPrice(_datasource, _gasLimit); 442 | if (price > 1 ether + tx.gasprice * _gasLimit) { 443 | return 0; // Unexpectedly high price 444 | } 445 | return oraclize.query2_withGasLimit.value(price)(0, _datasource, _arg1, _arg2, _gasLimit); 446 | } 447 | 448 | function oraclize_query(string memory _datasource, string[] memory _argN) oraclizeAPI internal returns (bytes32 _id) { 449 | uint price = oraclize.getPrice(_datasource); 450 | if (price > 1 ether + tx.gasprice * 200000) { 451 | return 0; // Unexpectedly high price 452 | } 453 | bytes memory args = stra2cbor(_argN); 454 | return oraclize.queryN.value(price)(0, _datasource, args); 455 | } 456 | 457 | function oraclize_query(uint _timestamp, string memory _datasource, string[] memory _argN) oraclizeAPI internal returns (bytes32 _id) { 458 | uint price = oraclize.getPrice(_datasource); 459 | if (price > 1 ether + tx.gasprice * 200000) { 460 | return 0; // Unexpectedly high price 461 | } 462 | bytes memory args = stra2cbor(_argN); 463 | return oraclize.queryN.value(price)(_timestamp, _datasource, args); 464 | } 465 | 466 | function oraclize_query(uint _timestamp, string memory _datasource, string[] memory _argN, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 467 | uint price = oraclize.getPrice(_datasource, _gasLimit); 468 | if (price > 1 ether + tx.gasprice * _gasLimit) { 469 | return 0; // Unexpectedly high price 470 | } 471 | bytes memory args = stra2cbor(_argN); 472 | return oraclize.queryN_withGasLimit.value(price)(_timestamp, _datasource, args, _gasLimit); 473 | } 474 | 475 | function oraclize_query(string memory _datasource, string[] memory _argN, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 476 | uint price = oraclize.getPrice(_datasource, _gasLimit); 477 | if (price > 1 ether + tx.gasprice * _gasLimit) { 478 | return 0; // Unexpectedly high price 479 | } 480 | bytes memory args = stra2cbor(_argN); 481 | return oraclize.queryN_withGasLimit.value(price)(0, _datasource, args, _gasLimit); 482 | } 483 | 484 | function oraclize_query(string memory _datasource, string[1] memory _args) oraclizeAPI internal returns (bytes32 _id) { 485 | string[] memory dynargs = new string[](1); 486 | dynargs[0] = _args[0]; 487 | return oraclize_query(_datasource, dynargs); 488 | } 489 | 490 | function oraclize_query(uint _timestamp, string memory _datasource, string[1] memory _args) oraclizeAPI internal returns (bytes32 _id) { 491 | string[] memory dynargs = new string[](1); 492 | dynargs[0] = _args[0]; 493 | return oraclize_query(_timestamp, _datasource, dynargs); 494 | } 495 | 496 | function oraclize_query(uint _timestamp, string memory _datasource, string[1] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 497 | string[] memory dynargs = new string[](1); 498 | dynargs[0] = _args[0]; 499 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 500 | } 501 | 502 | function oraclize_query(string memory _datasource, string[1] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 503 | string[] memory dynargs = new string[](1); 504 | dynargs[0] = _args[0]; 505 | return oraclize_query(_datasource, dynargs, _gasLimit); 506 | } 507 | 508 | function oraclize_query(string memory _datasource, string[2] memory _args) oraclizeAPI internal returns (bytes32 _id) { 509 | string[] memory dynargs = new string[](2); 510 | dynargs[0] = _args[0]; 511 | dynargs[1] = _args[1]; 512 | return oraclize_query(_datasource, dynargs); 513 | } 514 | 515 | function oraclize_query(uint _timestamp, string memory _datasource, string[2] memory _args) oraclizeAPI internal returns (bytes32 _id) { 516 | string[] memory dynargs = new string[](2); 517 | dynargs[0] = _args[0]; 518 | dynargs[1] = _args[1]; 519 | return oraclize_query(_timestamp, _datasource, dynargs); 520 | } 521 | 522 | function oraclize_query(uint _timestamp, string memory _datasource, string[2] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 523 | string[] memory dynargs = new string[](2); 524 | dynargs[0] = _args[0]; 525 | dynargs[1] = _args[1]; 526 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 527 | } 528 | 529 | function oraclize_query(string memory _datasource, string[2] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 530 | string[] memory dynargs = new string[](2); 531 | dynargs[0] = _args[0]; 532 | dynargs[1] = _args[1]; 533 | return oraclize_query(_datasource, dynargs, _gasLimit); 534 | } 535 | 536 | function oraclize_query(string memory _datasource, string[3] memory _args) oraclizeAPI internal returns (bytes32 _id) { 537 | string[] memory dynargs = new string[](3); 538 | dynargs[0] = _args[0]; 539 | dynargs[1] = _args[1]; 540 | dynargs[2] = _args[2]; 541 | return oraclize_query(_datasource, dynargs); 542 | } 543 | 544 | function oraclize_query(uint _timestamp, string memory _datasource, string[3] memory _args) oraclizeAPI internal returns (bytes32 _id) { 545 | string[] memory dynargs = new string[](3); 546 | dynargs[0] = _args[0]; 547 | dynargs[1] = _args[1]; 548 | dynargs[2] = _args[2]; 549 | return oraclize_query(_timestamp, _datasource, dynargs); 550 | } 551 | 552 | function oraclize_query(uint _timestamp, string memory _datasource, string[3] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 553 | string[] memory dynargs = new string[](3); 554 | dynargs[0] = _args[0]; 555 | dynargs[1] = _args[1]; 556 | dynargs[2] = _args[2]; 557 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 558 | } 559 | 560 | function oraclize_query(string memory _datasource, string[3] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 561 | string[] memory dynargs = new string[](3); 562 | dynargs[0] = _args[0]; 563 | dynargs[1] = _args[1]; 564 | dynargs[2] = _args[2]; 565 | return oraclize_query(_datasource, dynargs, _gasLimit); 566 | } 567 | 568 | function oraclize_query(string memory _datasource, string[4] memory _args) oraclizeAPI internal returns (bytes32 _id) { 569 | string[] memory dynargs = new string[](4); 570 | dynargs[0] = _args[0]; 571 | dynargs[1] = _args[1]; 572 | dynargs[2] = _args[2]; 573 | dynargs[3] = _args[3]; 574 | return oraclize_query(_datasource, dynargs); 575 | } 576 | 577 | function oraclize_query(uint _timestamp, string memory _datasource, string[4] memory _args) oraclizeAPI internal returns (bytes32 _id) { 578 | string[] memory dynargs = new string[](4); 579 | dynargs[0] = _args[0]; 580 | dynargs[1] = _args[1]; 581 | dynargs[2] = _args[2]; 582 | dynargs[3] = _args[3]; 583 | return oraclize_query(_timestamp, _datasource, dynargs); 584 | } 585 | 586 | function oraclize_query(uint _timestamp, string memory _datasource, string[4] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 587 | string[] memory dynargs = new string[](4); 588 | dynargs[0] = _args[0]; 589 | dynargs[1] = _args[1]; 590 | dynargs[2] = _args[2]; 591 | dynargs[3] = _args[3]; 592 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 593 | } 594 | 595 | function oraclize_query(string memory _datasource, string[4] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 596 | string[] memory dynargs = new string[](4); 597 | dynargs[0] = _args[0]; 598 | dynargs[1] = _args[1]; 599 | dynargs[2] = _args[2]; 600 | dynargs[3] = _args[3]; 601 | return oraclize_query(_datasource, dynargs, _gasLimit); 602 | } 603 | 604 | function oraclize_query(string memory _datasource, string[5] memory _args) oraclizeAPI internal returns (bytes32 _id) { 605 | string[] memory dynargs = new string[](5); 606 | dynargs[0] = _args[0]; 607 | dynargs[1] = _args[1]; 608 | dynargs[2] = _args[2]; 609 | dynargs[3] = _args[3]; 610 | dynargs[4] = _args[4]; 611 | return oraclize_query(_datasource, dynargs); 612 | } 613 | 614 | function oraclize_query(uint _timestamp, string memory _datasource, string[5] memory _args) oraclizeAPI internal returns (bytes32 _id) { 615 | string[] memory dynargs = new string[](5); 616 | dynargs[0] = _args[0]; 617 | dynargs[1] = _args[1]; 618 | dynargs[2] = _args[2]; 619 | dynargs[3] = _args[3]; 620 | dynargs[4] = _args[4]; 621 | return oraclize_query(_timestamp, _datasource, dynargs); 622 | } 623 | 624 | function oraclize_query(uint _timestamp, string memory _datasource, string[5] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 625 | string[] memory dynargs = new string[](5); 626 | dynargs[0] = _args[0]; 627 | dynargs[1] = _args[1]; 628 | dynargs[2] = _args[2]; 629 | dynargs[3] = _args[3]; 630 | dynargs[4] = _args[4]; 631 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 632 | } 633 | 634 | function oraclize_query(string memory _datasource, string[5] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 635 | string[] memory dynargs = new string[](5); 636 | dynargs[0] = _args[0]; 637 | dynargs[1] = _args[1]; 638 | dynargs[2] = _args[2]; 639 | dynargs[3] = _args[3]; 640 | dynargs[4] = _args[4]; 641 | return oraclize_query(_datasource, dynargs, _gasLimit); 642 | } 643 | 644 | function oraclize_query(string memory _datasource, bytes[] memory _argN) oraclizeAPI internal returns (bytes32 _id) { 645 | uint price = oraclize.getPrice(_datasource); 646 | if (price > 1 ether + tx.gasprice * 200000) { 647 | return 0; // Unexpectedly high price 648 | } 649 | bytes memory args = ba2cbor(_argN); 650 | return oraclize.queryN.value(price)(0, _datasource, args); 651 | } 652 | 653 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[] memory _argN) oraclizeAPI internal returns (bytes32 _id) { 654 | uint price = oraclize.getPrice(_datasource); 655 | if (price > 1 ether + tx.gasprice * 200000) { 656 | return 0; // Unexpectedly high price 657 | } 658 | bytes memory args = ba2cbor(_argN); 659 | return oraclize.queryN.value(price)(_timestamp, _datasource, args); 660 | } 661 | 662 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[] memory _argN, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 663 | uint price = oraclize.getPrice(_datasource, _gasLimit); 664 | if (price > 1 ether + tx.gasprice * _gasLimit) { 665 | return 0; // Unexpectedly high price 666 | } 667 | bytes memory args = ba2cbor(_argN); 668 | return oraclize.queryN_withGasLimit.value(price)(_timestamp, _datasource, args, _gasLimit); 669 | } 670 | 671 | function oraclize_query(string memory _datasource, bytes[] memory _argN, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 672 | uint price = oraclize.getPrice(_datasource, _gasLimit); 673 | if (price > 1 ether + tx.gasprice * _gasLimit) { 674 | return 0; // Unexpectedly high price 675 | } 676 | bytes memory args = ba2cbor(_argN); 677 | return oraclize.queryN_withGasLimit.value(price)(0, _datasource, args, _gasLimit); 678 | } 679 | 680 | function oraclize_query(string memory _datasource, bytes[1] memory _args) oraclizeAPI internal returns (bytes32 _id) { 681 | bytes[] memory dynargs = new bytes[](1); 682 | dynargs[0] = _args[0]; 683 | return oraclize_query(_datasource, dynargs); 684 | } 685 | 686 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[1] memory _args) oraclizeAPI internal returns (bytes32 _id) { 687 | bytes[] memory dynargs = new bytes[](1); 688 | dynargs[0] = _args[0]; 689 | return oraclize_query(_timestamp, _datasource, dynargs); 690 | } 691 | 692 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[1] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 693 | bytes[] memory dynargs = new bytes[](1); 694 | dynargs[0] = _args[0]; 695 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 696 | } 697 | 698 | function oraclize_query(string memory _datasource, bytes[1] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 699 | bytes[] memory dynargs = new bytes[](1); 700 | dynargs[0] = _args[0]; 701 | return oraclize_query(_datasource, dynargs, _gasLimit); 702 | } 703 | 704 | function oraclize_query(string memory _datasource, bytes[2] memory _args) oraclizeAPI internal returns (bytes32 _id) { 705 | bytes[] memory dynargs = new bytes[](2); 706 | dynargs[0] = _args[0]; 707 | dynargs[1] = _args[1]; 708 | return oraclize_query(_datasource, dynargs); 709 | } 710 | 711 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[2] memory _args) oraclizeAPI internal returns (bytes32 _id) { 712 | bytes[] memory dynargs = new bytes[](2); 713 | dynargs[0] = _args[0]; 714 | dynargs[1] = _args[1]; 715 | return oraclize_query(_timestamp, _datasource, dynargs); 716 | } 717 | 718 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[2] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 719 | bytes[] memory dynargs = new bytes[](2); 720 | dynargs[0] = _args[0]; 721 | dynargs[1] = _args[1]; 722 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 723 | } 724 | 725 | function oraclize_query(string memory _datasource, bytes[2] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 726 | bytes[] memory dynargs = new bytes[](2); 727 | dynargs[0] = _args[0]; 728 | dynargs[1] = _args[1]; 729 | return oraclize_query(_datasource, dynargs, _gasLimit); 730 | } 731 | 732 | function oraclize_query(string memory _datasource, bytes[3] memory _args) oraclizeAPI internal returns (bytes32 _id) { 733 | bytes[] memory dynargs = new bytes[](3); 734 | dynargs[0] = _args[0]; 735 | dynargs[1] = _args[1]; 736 | dynargs[2] = _args[2]; 737 | return oraclize_query(_datasource, dynargs); 738 | } 739 | 740 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[3] memory _args) oraclizeAPI internal returns (bytes32 _id) { 741 | bytes[] memory dynargs = new bytes[](3); 742 | dynargs[0] = _args[0]; 743 | dynargs[1] = _args[1]; 744 | dynargs[2] = _args[2]; 745 | return oraclize_query(_timestamp, _datasource, dynargs); 746 | } 747 | 748 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[3] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 749 | bytes[] memory dynargs = new bytes[](3); 750 | dynargs[0] = _args[0]; 751 | dynargs[1] = _args[1]; 752 | dynargs[2] = _args[2]; 753 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 754 | } 755 | 756 | function oraclize_query(string memory _datasource, bytes[3] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 757 | bytes[] memory dynargs = new bytes[](3); 758 | dynargs[0] = _args[0]; 759 | dynargs[1] = _args[1]; 760 | dynargs[2] = _args[2]; 761 | return oraclize_query(_datasource, dynargs, _gasLimit); 762 | } 763 | 764 | function oraclize_query(string memory _datasource, bytes[4] memory _args) oraclizeAPI internal returns (bytes32 _id) { 765 | bytes[] memory dynargs = new bytes[](4); 766 | dynargs[0] = _args[0]; 767 | dynargs[1] = _args[1]; 768 | dynargs[2] = _args[2]; 769 | dynargs[3] = _args[3]; 770 | return oraclize_query(_datasource, dynargs); 771 | } 772 | 773 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[4] memory _args) oraclizeAPI internal returns (bytes32 _id) { 774 | bytes[] memory dynargs = new bytes[](4); 775 | dynargs[0] = _args[0]; 776 | dynargs[1] = _args[1]; 777 | dynargs[2] = _args[2]; 778 | dynargs[3] = _args[3]; 779 | return oraclize_query(_timestamp, _datasource, dynargs); 780 | } 781 | 782 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[4] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 783 | bytes[] memory dynargs = new bytes[](4); 784 | dynargs[0] = _args[0]; 785 | dynargs[1] = _args[1]; 786 | dynargs[2] = _args[2]; 787 | dynargs[3] = _args[3]; 788 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 789 | } 790 | 791 | function oraclize_query(string memory _datasource, bytes[4] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 792 | bytes[] memory dynargs = new bytes[](4); 793 | dynargs[0] = _args[0]; 794 | dynargs[1] = _args[1]; 795 | dynargs[2] = _args[2]; 796 | dynargs[3] = _args[3]; 797 | return oraclize_query(_datasource, dynargs, _gasLimit); 798 | } 799 | 800 | function oraclize_query(string memory _datasource, bytes[5] memory _args) oraclizeAPI internal returns (bytes32 _id) { 801 | bytes[] memory dynargs = new bytes[](5); 802 | dynargs[0] = _args[0]; 803 | dynargs[1] = _args[1]; 804 | dynargs[2] = _args[2]; 805 | dynargs[3] = _args[3]; 806 | dynargs[4] = _args[4]; 807 | return oraclize_query(_datasource, dynargs); 808 | } 809 | 810 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[5] memory _args) oraclizeAPI internal returns (bytes32 _id) { 811 | bytes[] memory dynargs = new bytes[](5); 812 | dynargs[0] = _args[0]; 813 | dynargs[1] = _args[1]; 814 | dynargs[2] = _args[2]; 815 | dynargs[3] = _args[3]; 816 | dynargs[4] = _args[4]; 817 | return oraclize_query(_timestamp, _datasource, dynargs); 818 | } 819 | 820 | function oraclize_query(uint _timestamp, string memory _datasource, bytes[5] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 821 | bytes[] memory dynargs = new bytes[](5); 822 | dynargs[0] = _args[0]; 823 | dynargs[1] = _args[1]; 824 | dynargs[2] = _args[2]; 825 | dynargs[3] = _args[3]; 826 | dynargs[4] = _args[4]; 827 | return oraclize_query(_timestamp, _datasource, dynargs, _gasLimit); 828 | } 829 | 830 | function oraclize_query(string memory _datasource, bytes[5] memory _args, uint _gasLimit) oraclizeAPI internal returns (bytes32 _id) { 831 | bytes[] memory dynargs = new bytes[](5); 832 | dynargs[0] = _args[0]; 833 | dynargs[1] = _args[1]; 834 | dynargs[2] = _args[2]; 835 | dynargs[3] = _args[3]; 836 | dynargs[4] = _args[4]; 837 | return oraclize_query(_datasource, dynargs, _gasLimit); 838 | } 839 | 840 | function oraclize_setProof(byte _proofP) oraclizeAPI internal { 841 | return oraclize.setProofType(_proofP); 842 | } 843 | 844 | 845 | function oraclize_cbAddress() oraclizeAPI internal returns (address _callbackAddress) { 846 | return oraclize.cbAddress(); 847 | } 848 | 849 | function getCodeSize(address _addr) view internal returns (uint _size) { 850 | assembly { 851 | _size := extcodesize(_addr) 852 | } 853 | } 854 | 855 | function oraclize_setCustomGasPrice(uint _gasPrice) oraclizeAPI internal { 856 | return oraclize.setCustomGasPrice(_gasPrice); 857 | } 858 | 859 | function oraclize_randomDS_getSessionPubKeyHash() oraclizeAPI internal returns (bytes32 _sessionKeyHash) { 860 | return oraclize.randomDS_getSessionPubKeyHash(); 861 | } 862 | 863 | function parseAddr(string memory _a) internal pure returns (address _parsedAddress) { 864 | bytes memory tmp = bytes(_a); 865 | uint160 iaddr = 0; 866 | uint160 b1; 867 | uint160 b2; 868 | for (uint i = 2; i < 2 + 2 * 20; i += 2) { 869 | iaddr *= 256; 870 | b1 = uint160(uint8(tmp[i])); 871 | b2 = uint160(uint8(tmp[i + 1])); 872 | if ((b1 >= 97) && (b1 <= 102)) { 873 | b1 -= 87; 874 | } else if ((b1 >= 65) && (b1 <= 70)) { 875 | b1 -= 55; 876 | } else if ((b1 >= 48) && (b1 <= 57)) { 877 | b1 -= 48; 878 | } 879 | if ((b2 >= 97) && (b2 <= 102)) { 880 | b2 -= 87; 881 | } else if ((b2 >= 65) && (b2 <= 70)) { 882 | b2 -= 55; 883 | } else if ((b2 >= 48) && (b2 <= 57)) { 884 | b2 -= 48; 885 | } 886 | iaddr += (b1 * 16 + b2); 887 | } 888 | return address(iaddr); 889 | } 890 | 891 | function strCompare(string memory _a, string memory _b) internal pure returns (int _returnCode) { 892 | bytes memory a = bytes(_a); 893 | bytes memory b = bytes(_b); 894 | uint minLength = a.length; 895 | if (b.length < minLength) { 896 | minLength = b.length; 897 | } 898 | for (uint i = 0; i < minLength; i ++) { 899 | if (a[i] < b[i]) { 900 | return -1; 901 | } else if (a[i] > b[i]) { 902 | return 1; 903 | } 904 | } 905 | if (a.length < b.length) { 906 | return -1; 907 | } else if (a.length > b.length) { 908 | return 1; 909 | } else { 910 | return 0; 911 | } 912 | } 913 | 914 | function indexOf(string memory _haystack, string memory _needle) internal pure returns (int _returnCode) { 915 | bytes memory h = bytes(_haystack); 916 | bytes memory n = bytes(_needle); 917 | if (h.length < 1 || n.length < 1 || (n.length > h.length)) { 918 | return -1; 919 | } else if (h.length > (2 ** 128 - 1)) { 920 | return -1; 921 | } else { 922 | uint subindex = 0; 923 | for (uint i = 0; i < h.length; i++) { 924 | if (h[i] == n[0]) { 925 | subindex = 1; 926 | while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex]) { 927 | subindex++; 928 | } 929 | if (subindex == n.length) { 930 | return int(i); 931 | } 932 | } 933 | } 934 | return -1; 935 | } 936 | } 937 | 938 | function strConcat(string memory _a, string memory _b) internal pure returns (string memory _concatenatedString) { 939 | return strConcat(_a, _b, "", "", ""); 940 | } 941 | 942 | function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory _concatenatedString) { 943 | return strConcat(_a, _b, _c, "", ""); 944 | } 945 | 946 | function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory _concatenatedString) { 947 | return strConcat(_a, _b, _c, _d, ""); 948 | } 949 | 950 | function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory _concatenatedString) { 951 | bytes memory _ba = bytes(_a); 952 | bytes memory _bb = bytes(_b); 953 | bytes memory _bc = bytes(_c); 954 | bytes memory _bd = bytes(_d); 955 | bytes memory _be = bytes(_e); 956 | string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); 957 | bytes memory babcde = bytes(abcde); 958 | uint k = 0; 959 | uint i = 0; 960 | for (i = 0; i < _ba.length; i++) { 961 | babcde[k++] = _ba[i]; 962 | } 963 | for (i = 0; i < _bb.length; i++) { 964 | babcde[k++] = _bb[i]; 965 | } 966 | for (i = 0; i < _bc.length; i++) { 967 | babcde[k++] = _bc[i]; 968 | } 969 | for (i = 0; i < _bd.length; i++) { 970 | babcde[k++] = _bd[i]; 971 | } 972 | for (i = 0; i < _be.length; i++) { 973 | babcde[k++] = _be[i]; 974 | } 975 | return string(babcde); 976 | } 977 | 978 | function safeParseInt(string memory _a) internal pure returns (uint _parsedInt) { 979 | return safeParseInt(_a, 0); 980 | } 981 | 982 | function safeParseInt(string memory _a, uint _b) internal pure returns (uint _parsedInt) { 983 | bytes memory bresult = bytes(_a); 984 | uint mint = 0; 985 | bool decimals = false; 986 | for (uint i = 0; i < bresult.length; i++) { 987 | if ((uint(uint8(bresult[i])) >= 48) && (uint(uint8(bresult[i])) <= 57)) { 988 | if (decimals) { 989 | if (_b == 0) break; 990 | else _b--; 991 | } 992 | mint *= 10; 993 | mint += uint(uint8(bresult[i])) - 48; 994 | } else if (uint(uint8(bresult[i])) == 46) { 995 | require(!decimals, 'More than one decimal encountered in string!'); 996 | decimals = true; 997 | } else { 998 | revert("Non-numeral character encountered in string!"); 999 | } 1000 | } 1001 | if (_b > 0) { 1002 | mint *= 10 ** _b; 1003 | } 1004 | return mint; 1005 | } 1006 | 1007 | function parseInt(string memory _a) internal pure returns (uint _parsedInt) { 1008 | return parseInt(_a, 0); 1009 | } 1010 | 1011 | function parseInt(string memory _a, uint _b) internal pure returns (uint _parsedInt) { 1012 | bytes memory bresult = bytes(_a); 1013 | uint mint = 0; 1014 | bool decimals = false; 1015 | for (uint i = 0; i < bresult.length; i++) { 1016 | if ((uint(uint8(bresult[i])) >= 48) && (uint(uint8(bresult[i])) <= 57)) { 1017 | if (decimals) { 1018 | if (_b == 0) { 1019 | break; 1020 | } else { 1021 | _b--; 1022 | } 1023 | } 1024 | mint *= 10; 1025 | mint += uint(uint8(bresult[i])) - 48; 1026 | } else if (uint(uint8(bresult[i])) == 46) { 1027 | decimals = true; 1028 | } 1029 | } 1030 | if (_b > 0) { 1031 | mint *= 10 ** _b; 1032 | } 1033 | return mint; 1034 | } 1035 | 1036 | function uint2str(uint _i) internal pure returns (string memory _uintAsString) { 1037 | if (_i == 0) { 1038 | return "0"; 1039 | } 1040 | uint j = _i; 1041 | uint len; 1042 | while (j != 0) { 1043 | len++; 1044 | j /= 10; 1045 | } 1046 | bytes memory bstr = new bytes(len); 1047 | uint k = len - 1; 1048 | while (_i != 0) { 1049 | bstr[k--] = byte(uint8(48 + _i % 10)); 1050 | _i /= 10; 1051 | } 1052 | return string(bstr); 1053 | } 1054 | 1055 | function stra2cbor(string[] memory _arr) internal pure returns (bytes memory _cborEncoding) { 1056 | safeMemoryCleaner(); 1057 | Buffer.buffer memory buf; 1058 | Buffer.init(buf, 1024); 1059 | buf.startArray(); 1060 | for (uint i = 0; i < _arr.length; i++) { 1061 | buf.encodeString(_arr[i]); 1062 | } 1063 | buf.endSequence(); 1064 | return buf.buf; 1065 | } 1066 | 1067 | function ba2cbor(bytes[] memory _arr) internal pure returns (bytes memory _cborEncoding) { 1068 | safeMemoryCleaner(); 1069 | Buffer.buffer memory buf; 1070 | Buffer.init(buf, 1024); 1071 | buf.startArray(); 1072 | for (uint i = 0; i < _arr.length; i++) { 1073 | buf.encodeBytes(_arr[i]); 1074 | } 1075 | buf.endSequence(); 1076 | return buf.buf; 1077 | } 1078 | 1079 | function oraclize_newRandomDSQuery(uint _delay, uint _nbytes, uint _customGasLimit) internal returns (bytes32 _queryId) { 1080 | require((_nbytes > 0) && (_nbytes <= 32)); 1081 | _delay *= 10; // Convert from seconds to ledger timer ticks 1082 | bytes memory nbytes = new bytes(1); 1083 | nbytes[0] = byte(uint8(_nbytes)); 1084 | bytes memory unonce = new bytes(32); 1085 | bytes memory sessionKeyHash = new bytes(32); 1086 | bytes32 sessionKeyHash_bytes32 = oraclize_randomDS_getSessionPubKeyHash(); 1087 | assembly { 1088 | mstore(unonce, 0x20) 1089 | /* 1090 | The following variables can be relaxed. 1091 | Check the relaxed random contract at https://github.com/oraclize/ethereum-examples 1092 | for an idea on how to override and replace commit hash variables. 1093 | */ 1094 | mstore(add(unonce, 0x20), xor(blockhash(sub(number, 1)), xor(coinbase, timestamp))) 1095 | mstore(sessionKeyHash, 0x20) 1096 | mstore(add(sessionKeyHash, 0x20), sessionKeyHash_bytes32) 1097 | } 1098 | bytes memory delay = new bytes(32); 1099 | assembly { 1100 | mstore(add(delay, 0x20), _delay) 1101 | } 1102 | bytes memory delay_bytes8 = new bytes(8); 1103 | copyBytes(delay, 24, 8, delay_bytes8, 0); 1104 | bytes[4] memory args = [unonce, nbytes, sessionKeyHash, delay]; 1105 | bytes32 queryId = oraclize_query("random", args, _customGasLimit); 1106 | bytes memory delay_bytes8_left = new bytes(8); 1107 | assembly { 1108 | let x := mload(add(delay_bytes8, 0x20)) 1109 | mstore8(add(delay_bytes8_left, 0x27), div(x, 0x100000000000000000000000000000000000000000000000000000000000000)) 1110 | mstore8(add(delay_bytes8_left, 0x26), div(x, 0x1000000000000000000000000000000000000000000000000000000000000)) 1111 | mstore8(add(delay_bytes8_left, 0x25), div(x, 0x10000000000000000000000000000000000000000000000000000000000)) 1112 | mstore8(add(delay_bytes8_left, 0x24), div(x, 0x100000000000000000000000000000000000000000000000000000000)) 1113 | mstore8(add(delay_bytes8_left, 0x23), div(x, 0x1000000000000000000000000000000000000000000000000000000)) 1114 | mstore8(add(delay_bytes8_left, 0x22), div(x, 0x10000000000000000000000000000000000000000000000000000)) 1115 | mstore8(add(delay_bytes8_left, 0x21), div(x, 0x100000000000000000000000000000000000000000000000000)) 1116 | mstore8(add(delay_bytes8_left, 0x20), div(x, 0x1000000000000000000000000000000000000000000000000)) 1117 | } 1118 | oraclize_randomDS_setCommitment(queryId, keccak256(abi.encodePacked(delay_bytes8_left, args[1], sha256(args[0]), args[2]))); 1119 | return queryId; 1120 | } 1121 | 1122 | function oraclize_randomDS_setCommitment(bytes32 _queryId, bytes32 _commitment) internal { 1123 | oraclize_randomDS_args[_queryId] = _commitment; 1124 | } 1125 | 1126 | function verifySig(bytes32 _tosignh, bytes memory _dersig, bytes memory _pubkey) internal returns (bool _sigVerified) { 1127 | bool sigok; 1128 | address signer; 1129 | bytes32 sigr; 1130 | bytes32 sigs; 1131 | bytes memory sigr_ = new bytes(32); 1132 | uint offset = 4 + (uint(uint8(_dersig[3])) - 0x20); 1133 | sigr_ = copyBytes(_dersig, offset, 32, sigr_, 0); 1134 | bytes memory sigs_ = new bytes(32); 1135 | offset += 32 + 2; 1136 | sigs_ = copyBytes(_dersig, offset + (uint(uint8(_dersig[offset - 1])) - 0x20), 32, sigs_, 0); 1137 | assembly { 1138 | sigr := mload(add(sigr_, 32)) 1139 | sigs := mload(add(sigs_, 32)) 1140 | } 1141 | (sigok, signer) = safer_ecrecover(_tosignh, 27, sigr, sigs); 1142 | if (address(uint160(uint256(keccak256(_pubkey)))) == signer) { 1143 | return true; 1144 | } else { 1145 | (sigok, signer) = safer_ecrecover(_tosignh, 28, sigr, sigs); 1146 | return (address(uint160(uint256(keccak256(_pubkey)))) == signer); 1147 | } 1148 | } 1149 | 1150 | function oraclize_randomDS_proofVerify__sessionKeyValidity(bytes memory _proof, uint _sig2offset) internal returns (bool _proofVerified) { 1151 | bool sigok; 1152 | // Random DS Proof Step 6: Verify the attestation signature, APPKEY1 must sign the sessionKey from the correct ledger app (CODEHASH) 1153 | bytes memory sig2 = new bytes(uint(uint8(_proof[_sig2offset + 1])) + 2); 1154 | copyBytes(_proof, _sig2offset, sig2.length, sig2, 0); 1155 | bytes memory appkey1_pubkey = new bytes(64); 1156 | copyBytes(_proof, 3 + 1, 64, appkey1_pubkey, 0); 1157 | bytes memory tosign2 = new bytes(1 + 65 + 32); 1158 | tosign2[0] = byte(uint8(1)); //role 1159 | copyBytes(_proof, _sig2offset - 65, 65, tosign2, 1); 1160 | bytes memory CODEHASH = hex"fd94fa71bc0ba10d39d464d0d8f465efeef0a2764e3887fcc9df41ded20f505c"; 1161 | copyBytes(CODEHASH, 0, 32, tosign2, 1 + 65); 1162 | sigok = verifySig(sha256(tosign2), sig2, appkey1_pubkey); 1163 | if (!sigok) { 1164 | return false; 1165 | } 1166 | // Random DS Proof Step 7: Verify the APPKEY1 provenance (must be signed by Ledger) 1167 | bytes memory LEDGERKEY = hex"7fb956469c5c9b89840d55b43537e66a98dd4811ea0a27224272c2e5622911e8537a2f8e86a46baec82864e98dd01e9ccc2f8bc5dfc9cbe5a91a290498dd96e4"; 1168 | bytes memory tosign3 = new bytes(1 + 65); 1169 | tosign3[0] = 0xFE; 1170 | copyBytes(_proof, 3, 65, tosign3, 1); 1171 | bytes memory sig3 = new bytes(uint(uint8(_proof[3 + 65 + 1])) + 2); 1172 | copyBytes(_proof, 3 + 65, sig3.length, sig3, 0); 1173 | sigok = verifySig(sha256(tosign3), sig3, LEDGERKEY); 1174 | return sigok; 1175 | } 1176 | 1177 | function oraclize_randomDS_proofVerify__returnCode(bytes32 _queryId, string memory _result, bytes memory _proof) internal returns (uint8 _returnCode) { 1178 | // Random DS Proof Step 1: The prefix has to match 'LP\x01' (Ledger Proof version 1) 1179 | if ((_proof[0] != "L") || (_proof[1] != "P") || (uint8(_proof[2]) != uint8(1))) { 1180 | return 1; 1181 | } 1182 | bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName()); 1183 | if (!proofVerified) { 1184 | return 2; 1185 | } 1186 | return 0; 1187 | } 1188 | 1189 | function matchBytes32Prefix(bytes32 _content, bytes memory _prefix, uint _nRandomBytes) internal pure returns (bool _matchesPrefix) { 1190 | bool match_ = true; 1191 | require(_prefix.length == _nRandomBytes); 1192 | for (uint256 i = 0; i< _nRandomBytes; i++) { 1193 | if (_content[i] != _prefix[i]) { 1194 | match_ = false; 1195 | } 1196 | } 1197 | return match_; 1198 | } 1199 | 1200 | function oraclize_randomDS_proofVerify__main(bytes memory _proof, bytes32 _queryId, bytes memory _result, string memory _contextName) internal returns (bool _proofVerified) { 1201 | // Random DS Proof Step 2: The unique keyhash has to match with the sha256 of (context name + _queryId) 1202 | uint ledgerProofLength = 3 + 65 + (uint(uint8(_proof[3 + 65 + 1])) + 2) + 32; 1203 | bytes memory keyhash = new bytes(32); 1204 | copyBytes(_proof, ledgerProofLength, 32, keyhash, 0); 1205 | if (!(keccak256(keyhash) == keccak256(abi.encodePacked(sha256(abi.encodePacked(_contextName, _queryId)))))) { 1206 | return false; 1207 | } 1208 | bytes memory sig1 = new bytes(uint(uint8(_proof[ledgerProofLength + (32 + 8 + 1 + 32) + 1])) + 2); 1209 | copyBytes(_proof, ledgerProofLength + (32 + 8 + 1 + 32), sig1.length, sig1, 0); 1210 | // Random DS Proof 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) 1211 | if (!matchBytes32Prefix(sha256(sig1), _result, uint(uint8(_proof[ledgerProofLength + 32 + 8])))) { 1212 | return false; 1213 | } 1214 | // Random DS Proof Step 4: Commitment match verification, keccak256(delay, nbytes, unonce, sessionKeyHash) == commitment in storage. 1215 | // This is to verify that the computed args match with the ones specified in the query. 1216 | bytes memory commitmentSlice1 = new bytes(8 + 1 + 32); 1217 | copyBytes(_proof, ledgerProofLength + 32, 8 + 1 + 32, commitmentSlice1, 0); 1218 | bytes memory sessionPubkey = new bytes(64); 1219 | uint sig2offset = ledgerProofLength + 32 + (8 + 1 + 32) + sig1.length + 65; 1220 | copyBytes(_proof, sig2offset - 64, 64, sessionPubkey, 0); 1221 | bytes32 sessionPubkeyHash = sha256(sessionPubkey); 1222 | if (oraclize_randomDS_args[_queryId] == keccak256(abi.encodePacked(commitmentSlice1, sessionPubkeyHash))) { //unonce, nbytes and sessionKeyHash match 1223 | delete oraclize_randomDS_args[_queryId]; 1224 | } else return false; 1225 | // Random DS Proof Step 5: Validity verification for sig1 (keyhash and args signed with the sessionKey) 1226 | bytes memory tosign1 = new bytes(32 + 8 + 1 + 32); 1227 | copyBytes(_proof, ledgerProofLength, 32 + 8 + 1 + 32, tosign1, 0); 1228 | if (!verifySig(sha256(tosign1), sig1, sessionPubkey)) { 1229 | return false; 1230 | } 1231 | // Verify if sessionPubkeyHash was verified already, if not.. let's do it! 1232 | if (!oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash]) { 1233 | oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] = oraclize_randomDS_proofVerify__sessionKeyValidity(_proof, sig2offset); 1234 | } 1235 | return oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash]; 1236 | } 1237 | /* 1238 | The following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license 1239 | */ 1240 | function copyBytes(bytes memory _from, uint _fromOffset, uint _length, bytes memory _to, uint _toOffset) internal pure returns (bytes memory _copiedBytes) { 1241 | uint minLength = _length + _toOffset; 1242 | require(_to.length >= minLength); // Buffer too small. Should be a better way? 1243 | uint i = 32 + _fromOffset; // NOTE: the offset 32 is added to skip the `size` field of both bytes variables 1244 | uint j = 32 + _toOffset; 1245 | while (i < (32 + _fromOffset + _length)) { 1246 | assembly { 1247 | let tmp := mload(add(_from, i)) 1248 | mstore(add(_to, j), tmp) 1249 | } 1250 | i += 32; 1251 | j += 32; 1252 | } 1253 | return _to; 1254 | } 1255 | /* 1256 | The following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license 1257 | Duplicate Solidity's ecrecover, but catching the CALL return value 1258 | */ 1259 | function safer_ecrecover(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) internal returns (bool _success, address _recoveredAddress) { 1260 | /* 1261 | We do our own memory management here. Solidity uses memory offset 1262 | 0x40 to store the current end of memory. We write past it (as 1263 | writes are memory extensions), but don't update the offset so 1264 | Solidity will reuse it. The memory used here is only needed for 1265 | this context. 1266 | FIXME: inline assembly can't access return values 1267 | */ 1268 | bool ret; 1269 | address addr; 1270 | assembly { 1271 | let size := mload(0x40) 1272 | mstore(size, _hash) 1273 | mstore(add(size, 32), _v) 1274 | mstore(add(size, 64), _r) 1275 | mstore(add(size, 96), _s) 1276 | ret := call(3000, 1, 0, size, 128, size, 32) // NOTE: we can reuse the request memory because we deal with the return code. 1277 | addr := mload(size) 1278 | } 1279 | return (ret, addr); 1280 | } 1281 | /* 1282 | The following function has been written by Alex Beregszaszi (@axic), use it under the terms of the MIT license 1283 | */ 1284 | function ecrecovery(bytes32 _hash, bytes memory _sig) internal returns (bool _success, address _recoveredAddress) { 1285 | bytes32 r; 1286 | bytes32 s; 1287 | uint8 v; 1288 | if (_sig.length != 65) { 1289 | return (false, address(0)); 1290 | } 1291 | /* 1292 | The signature format is a compact form of: 1293 | {bytes32 r}{bytes32 s}{uint8 v} 1294 | Compact means, uint8 is not padded to 32 bytes. 1295 | */ 1296 | assembly { 1297 | r := mload(add(_sig, 32)) 1298 | s := mload(add(_sig, 64)) 1299 | /* 1300 | Here we are loading the last 32 bytes. We exploit the fact that 1301 | 'mload' will pad with zeroes if we overread. 1302 | There is no 'mload8' to do this, but that would be nicer. 1303 | */ 1304 | v := byte(0, mload(add(_sig, 96))) 1305 | /* 1306 | Alternative solution: 1307 | 'byte' is not working due to the Solidity parser, so lets 1308 | use the second best option, 'and' 1309 | v := and(mload(add(_sig, 65)), 255) 1310 | */ 1311 | } 1312 | /* 1313 | albeit non-transactional signatures are not specified by the YP, one would expect it 1314 | to match the YP range of [27, 28] 1315 | geth uses [0, 1] and some clients have followed. This might change, see: 1316 | https://github.com/ethereum/go-ethereum/issues/2053 1317 | */ 1318 | if (v < 27) { 1319 | v += 27; 1320 | } 1321 | if (v != 27 && v != 28) { 1322 | return (false, address(0)); 1323 | } 1324 | return safer_ecrecover(_hash, v, r, s); 1325 | } 1326 | 1327 | function safeMemoryCleaner() internal pure { 1328 | assembly { 1329 | let fmem := mload(0x40) 1330 | codecopy(fmem, codesize, sub(msize, fmem)) 1331 | } 1332 | } 1333 | } 1334 | /* 1335 | 1336 | END ORACLIZE_API 1337 | 1338 | */ -------------------------------------------------------------------------------- /eth-contracts/contracts/SolnSquareVerifier.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.6.0; 2 | 3 | // TODO define a contract call to the zokrates generated solidity contract or 4 | 5 | 6 | 7 | // TODO define another contract named SolnSquareVerifier that inherits from your ERC721Mintable class 8 | 9 | 10 | 11 | // TODO define a solutions struct that can hold an index & an address 12 | 13 | 14 | // TODO define an array of the above struct 15 | 16 | 17 | // TODO define a mapping to store unique solutions submitted 18 | 19 | 20 | 21 | // TODO Create an event to emit when a solution is added 22 | 23 | 24 | 25 | // TODO Create a function to add the solutions to the array and emit the event 26 | 27 | 28 | 29 | // TODO Create a function to mint new NFT only after the solution has been verified 30 | // - make sure the solution is unique (has not been used before) 31 | // - make sure you handle metadata as well as tokenSuplly 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /eth-contracts/migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /eth-contracts/migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | // migrating the appropriate contracts 2 | var SquareVerifier = artifacts.require("./SquareVerifier.sol"); 3 | var SolnSquareVerifier = artifacts.require("./SolnSquareVerifier.sol"); 4 | 5 | module.exports = function(deployer) { 6 | deployer.deploy(SquareVerifier); 7 | deployer.deploy(SolnSquareVerifier); 8 | }; 9 | -------------------------------------------------------------------------------- /eth-contracts/test/TestERC721Mintable.js: -------------------------------------------------------------------------------- 1 | var ERC721MintableComplete = artifacts.require('ERC721MintableComplete'); 2 | 3 | contract('TestERC721Mintable', accounts => { 4 | 5 | const account_one = accounts[0]; 6 | const account_two = accounts[1]; 7 | 8 | describe('match erc721 spec', function () { 9 | beforeEach(async function () { 10 | this.contract = await ERC721MintableComplete.new({from: account_one}); 11 | 12 | // TODO: mint multiple tokens 13 | }) 14 | 15 | it('should return total supply', async function () { 16 | 17 | }) 18 | 19 | it('should get token balance', async function () { 20 | 21 | }) 22 | 23 | // token uri should be complete i.e: https://s3-us-west-2.amazonaws.com/udacity-blockchain/capstone/1 24 | it('should return token uri', async function () { 25 | 26 | }) 27 | 28 | it('should transfer token from one owner to another', async function () { 29 | 30 | }) 31 | }); 32 | 33 | describe('have ownership properties', function () { 34 | beforeEach(async function () { 35 | this.contract = await ERC721MintableComplete.new({from: account_one}); 36 | }) 37 | 38 | it('should fail when minting when address is not contract owner', async function () { 39 | 40 | }) 41 | 42 | it('should return contract owner', async function () { 43 | 44 | }) 45 | 46 | }); 47 | }) -------------------------------------------------------------------------------- /eth-contracts/test/TestSolnSquareVerifier.js: -------------------------------------------------------------------------------- 1 | // Test if a new solution can be added for contract - SolnSquareVerifier 2 | 3 | // Test if an ERC721 token can be minted for contract - SolnSquareVerifier 4 | -------------------------------------------------------------------------------- /eth-contracts/test/TestSquareVerifier.js: -------------------------------------------------------------------------------- 1 | // define a variable to import the or solidity contract generated by Zokrates 2 | 3 | // Test verification with correct proof 4 | // - use the contents from proof.json generated from zokrates steps 5 | 6 | 7 | // Test verification with incorrect proof 8 | -------------------------------------------------------------------------------- /eth-contracts/truffle-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file to configure your truffle project. It's seeded with some 3 | * common settings for different networks and features like migrations, 4 | * compilation and testing. Uncomment the ones you need or modify 5 | * them to suit your project as necessary. 6 | * 7 | * More information about configuration can be found at: 8 | * 9 | * truffleframework.com/docs/advanced/configuration 10 | * 11 | * To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) 12 | * to sign your transactions before they're sent to a remote public node. Infura API 13 | * keys are available for free at: infura.io/register 14 | * 15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate 16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this 17 | * phrase from a file you've .gitignored so it doesn't accidentally become public. 18 | * 19 | */ 20 | 21 | // const HDWalletProvider = require('truffle-hdwallet-provider'); 22 | // const infuraKey = "fj4jll3k....."; 23 | // 24 | // const fs = require('fs'); 25 | // const mnemonic = fs.readFileSync(".secret").toString().trim(); 26 | 27 | module.exports = { 28 | /** 29 | * Networks define how you connect to your ethereum client and let you set the 30 | * defaults web3 uses to send transactions. If you don't specify one truffle 31 | * will spin up a development blockchain for you on port 9545 when you 32 | * run `develop` or `test`. You can ask a truffle command to use a specific 33 | * network from the command line, e.g 34 | * 35 | * $ truffle test --network 36 | */ 37 | 38 | networks: { 39 | // Useful for testing. The `development` name is special - truffle uses it by default 40 | // if it's defined here and no other network is specified at the command line. 41 | // You should run a client (like ganache-cli, geth or parity) in a separate terminal 42 | // tab if you use this network and you must also set the `host`, `port` and `network_id` 43 | // options below to some value. 44 | // 45 | development: { 46 | host: "127.0.0.1", // Localhost (default: none) 47 | port: 8545, // Standard Ethereum port (default: none) 48 | network_id: "*", // Any network (default: none) 49 | }, 50 | 51 | // Another network with more advanced options... 52 | // advanced: { 53 | // port: 8777, // Custom port 54 | // network_id: 1342, // Custom network 55 | // gas: 8500000, // Gas sent with each transaction (default: ~6700000) 56 | // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) 57 | // from:
, // Account to send txs from (default: accounts[0]) 58 | // websockets: true // Enable EventEmitter interface for web3 (default: false) 59 | // }, 60 | 61 | // Useful for deploying to a public network. 62 | // NB: It's important to wrap the provider as a function. 63 | // ropsten: { 64 | // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/${infuraKey}`), 65 | // network_id: 3, // Ropsten's id 66 | // gas: 5500000, // Ropsten has a lower block limit than mainnet 67 | // confirmations: 2, // # of confs to wait between deployments. (default: 0) 68 | // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) 69 | // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) 70 | // }, 71 | 72 | // Useful for private networks 73 | // private: { 74 | // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), 75 | // network_id: 2111, // This network is yours, in the cloud. 76 | // production: true // Treats this network as if it was a public net. (default: false) 77 | // } 78 | }, 79 | 80 | // Set default mocha options here, use special reporters etc. 81 | mocha: { 82 | // timeout: 100000 83 | }, 84 | 85 | // Configure your compilers 86 | compilers: { 87 | solc: { 88 | // version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version) 89 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) 90 | // settings: { // See the solidity docs for advice about optimization and evmVersion 91 | // optimizer: { 92 | // enabled: false, 93 | // runs: 200 94 | // }, 95 | // evmVersion: "byzantium" 96 | // } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "capstone", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "lite-server", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "pk (https://ipfs.infura.io/ipfs/QmSXiR9Khm3yo1J67nUopvVBxFJ8YGN2fUGZ34Etr3m92x/)", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "lite-server": "2.4.0" 15 | }, 16 | "dependencies": { 17 | "openzeppelin-solidity": "^2.2.0", 18 | "solc": "^0.5.2", 19 | "solc-js": "^0.5.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /zokrates/code/square/square.code: -------------------------------------------------------------------------------- 1 | def main(private field , field ) -> (field): 2 | field = if * == then 1 else 0 fi 3 | return 4 | --------------------------------------------------------------------------------