├── .babelrc
├── src
├── logo.png
├── components
│ ├── App.css
│ └── App.js
├── contracts
│ ├── Color.sol
│ ├── Migrations.sol
│ └── ERC721Full.sol
├── index.js
├── serviceWorker.js
└── abis
│ └── Migrations.json
├── public
├── favicon.ico
├── manifest.json
└── index.html
├── migrations
├── 2_deploy_contracts.js
└── 1_initial_migration.js
├── .gitignore
├── truffle-config.js
├── package.json
└── test
└── Color.test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2", "stage-3"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opensea712/NFT_tutorial/HEAD/src/logo.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opensea712/NFT_tutorial/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/migrations/2_deploy_contracts.js:
--------------------------------------------------------------------------------
1 | const Color = artifacts.require("Color");
2 |
3 | module.exports = function(deployer) {
4 | deployer.deploy(Color);
5 | };
6 |
--------------------------------------------------------------------------------
/src/components/App.css:
--------------------------------------------------------------------------------
1 | /* Styles go here */
2 |
3 | .token {
4 | height: 150px;
5 | width: 150px;
6 | border-radius: 50%;
7 | display: inline-block;
8 | }
9 |
--------------------------------------------------------------------------------
/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | const Migrations = artifacts.require("Migrations");
2 |
3 | module.exports = function(deployer) {
4 | deployer.deploy(Migrations);
5 | };
6 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Starter Kit",
3 | "name": "Dapp University Starter Kit",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/truffle-config.js:
--------------------------------------------------------------------------------
1 | require('babel-register');
2 | require('babel-polyfill');
3 |
4 | module.exports = {
5 | networks: {
6 | development: {
7 | host: "127.0.0.1",
8 | port: 7545,
9 | network_id: "*" // Match any network id
10 | },
11 | },
12 | contracts_directory: './src/contracts/',
13 | contracts_build_directory: './src/abis/',
14 | compilers: {
15 | solc: {
16 | optimizer: {
17 | enabled: true,
18 | runs: 200
19 | }
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/contracts/Color.sol:
--------------------------------------------------------------------------------
1 | pragma solidity 0.5.0;
2 |
3 | import "./ERC721Full.sol";
4 |
5 | contract Color is ERC721Full {
6 | string[] public colors;
7 | mapping(string => bool) _colorExists;
8 |
9 | constructor() ERC721Full("Color", "COLOR") public {
10 | }
11 |
12 | // E.G. color = "#FFFFFF"
13 | function mint(string memory _color) public {
14 | require(!_colorExists[_color]);
15 | uint _id = colors.push(_color);
16 | _mint(msg.sender, _id);
17 | _colorExists[_color] = true;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import 'bootstrap/dist/css/bootstrap.css'
4 | import App from './components/App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/src/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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ntf-tutorial",
3 | "version": "0.1.0",
4 | "description": "NFT Tutorial with ERC-721",
5 | "dependencies": {
6 | "@openzeppelin/contracts": "^2.3.0",
7 | "babel-polyfill": "6.26.0",
8 | "babel-preset-env": "1.7.0",
9 | "babel-preset-es2015": "6.24.1",
10 | "babel-preset-stage-2": "6.24.1",
11 | "babel-preset-stage-3": "6.24.1",
12 | "babel-register": "6.26.0",
13 | "bootstrap": "4.3.1",
14 | "chai": "4.2.0",
15 | "chai-as-promised": "7.1.1",
16 | "chai-bignumber": "3.0.0",
17 | "react": "16.8.4",
18 | "react-bootstrap": "1.0.0-beta.5",
19 | "react-dom": "16.8.4",
20 | "react-scripts": "2.1.3",
21 | "truffle": "5.0.5",
22 | "truffle-flattener": "^1.4.2",
23 | "web3": "1.0.0-beta.55"
24 | },
25 | "scripts": {
26 | "start": "react-scripts start",
27 | "build": "react-scripts build",
28 | "test": "react-scripts test",
29 | "eject": "react-scripts eject"
30 | },
31 | "eslintConfig": {
32 | "extends": "react-app"
33 | },
34 | "browserslist": [
35 | ">0.2%",
36 | "not dead",
37 | "not ie <= 11",
38 | "not op_mini all"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
15 |
16 |
25 | Dapp University Starter Kit
26 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/test/Color.test.js:
--------------------------------------------------------------------------------
1 | const Color = artifacts.require('./Color.sol')
2 |
3 | require('chai')
4 | .use(require('chai-as-promised'))
5 | .should()
6 |
7 | contract('Color', (accounts) => {
8 | let contract
9 |
10 | before(async () => {
11 | contract = await Color.deployed()
12 | })
13 |
14 | describe('deployment', async () => {
15 | it('deploys successfully', async () => {
16 | const address = contract.address
17 | assert.notEqual(address, 0x0)
18 | assert.notEqual(address, '')
19 | assert.notEqual(address, null)
20 | assert.notEqual(address, undefined)
21 | })
22 |
23 | it('has a name', async () => {
24 | const name = await contract.name()
25 | assert.equal(name, 'Color')
26 | })
27 |
28 | it('has a symbol', async () => {
29 | const symbol = await contract.symbol()
30 | assert.equal(symbol, 'COLOR')
31 | })
32 |
33 | })
34 |
35 | describe('minting', async () => {
36 |
37 | it('creates a new token', async () => {
38 | const result = await contract.mint('#EC058E')
39 | const totalSupply = await contract.totalSupply()
40 | // SUCCESS
41 | assert.equal(totalSupply, 1)
42 | const event = result.logs[0].args
43 | assert.equal(event.tokenId.toNumber(), 1, 'id is correct')
44 | assert.equal(event.from, '0x0000000000000000000000000000000000000000', 'from is correct')
45 | assert.equal(event.to, accounts[0], 'to is correct')
46 |
47 | // FAILURE: cannot mint same color twice
48 | await contract.mint('#EC058E').should.be.rejected;
49 | })
50 | })
51 |
52 | describe('indexing', async () => {
53 | it('lists colors', async () => {
54 | // Mint 3 more tokens
55 | await contract.mint('#5386E4')
56 | await contract.mint('#FFFFFF')
57 | await contract.mint('#000000')
58 | const totalSupply = await contract.totalSupply()
59 |
60 | let color
61 | let result = []
62 |
63 | for (var i = 1; i <= totalSupply; i++) {
64 | color = await contract.colors(i - 1)
65 | result.push(color)
66 | }
67 |
68 | let expected = ['#EC058E', '#5386E4', '#FFFFFF', '#000000']
69 | assert.equal(result.join(','), expected.join(','))
70 | })
71 | })
72 |
73 | })
74 |
--------------------------------------------------------------------------------
/src/components/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Web3 from 'web3'
3 | import './App.css';
4 | import Color from '../abis/Color.json'
5 |
6 | class App extends Component {
7 |
8 | async componentWillMount() {
9 | await this.loadWeb3()
10 | await this.loadBlockchainData()
11 | }
12 |
13 | async loadWeb3() {
14 | if (window.ethereum) {
15 | window.web3 = new Web3(window.ethereum)
16 | await window.ethereum.enable()
17 | }
18 | else if (window.web3) {
19 | window.web3 = new Web3(window.web3.currentProvider)
20 | }
21 | else {
22 | window.alert('Non-Ethereum browser detected. You should consider trying MetaMask!')
23 | }
24 | }
25 |
26 | async loadBlockchainData() {
27 | const web3 = window.web3
28 | // Load account
29 | const accounts = await web3.eth.getAccounts()
30 | this.setState({ account: accounts[0] })
31 |
32 | const networkId = await web3.eth.net.getId()
33 | const networkData = Color.networks[networkId]
34 | if(networkData) {
35 | const abi = Color.abi
36 | const address = networkData.address
37 | const contract = new web3.eth.Contract(abi, address)
38 | this.setState({ contract })
39 | const totalSupply = await contract.methods.totalSupply().call()
40 | this.setState({ totalSupply })
41 | // Load Colors
42 | for (var i = 1; i <= totalSupply; i++) {
43 | const color = await contract.methods.colors(i - 1).call()
44 | this.setState({
45 | colors: [...this.state.colors, color]
46 | })
47 | }
48 | } else {
49 | window.alert('Smart contract not deployed to detected network.')
50 | }
51 | }
52 |
53 | mint = (color) => {
54 | this.state.contract.methods.mint(color).send({ from: this.state.account })
55 | .once('receipt', (receipt) => {
56 | this.setState({
57 | colors: [...this.state.colors, color]
58 | })
59 | })
60 | }
61 |
62 | constructor(props) {
63 | super(props)
64 | this.state = {
65 | account: '',
66 | contract: null,
67 | totalSupply: 0,
68 | colors: []
69 | }
70 | }
71 |
72 | render() {
73 | return (
74 |
75 |
90 |
91 |
92 |
93 |
94 |
Issue Token
95 |
112 |
113 |
114 |
115 |
116 |
117 | { this.state.colors.map((color, key) => {
118 | return(
119 |
120 |
121 |
{color}
122 |
123 | )
124 | })}
125 |
126 |
127 |
128 | );
129 | }
130 | }
131 |
132 | export default App;
133 |
--------------------------------------------------------------------------------
/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl)
104 | .then(response => {
105 | // Ensure service worker exists, and that we really are getting a JS file.
106 | const contentType = response.headers.get('content-type');
107 | if (
108 | response.status === 404 ||
109 | (contentType != null && contentType.indexOf('javascript') === -1)
110 | ) {
111 | // No service worker found. Probably a different app. Reload the page.
112 | navigator.serviceWorker.ready.then(registration => {
113 | registration.unregister().then(() => {
114 | window.location.reload();
115 | });
116 | });
117 | } else {
118 | // Service worker found. Proceed as normal.
119 | registerValidSW(swUrl, config);
120 | }
121 | })
122 | .catch(() => {
123 | console.log(
124 | 'No internet connection found. App is running in offline mode.'
125 | );
126 | });
127 | }
128 |
129 | export function unregister() {
130 | if ('serviceWorker' in navigator) {
131 | navigator.serviceWorker.ready.then(registration => {
132 | registration.unregister();
133 | });
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/contracts/ERC721Full.sol:
--------------------------------------------------------------------------------
1 |
2 | // File: @openzeppelin/contracts/introspection/IERC165.sol
3 |
4 | pragma solidity ^0.5.0;
5 |
6 | /**
7 | * @dev Interface of the ERC165 standard, as defined in the
8 | * [EIP](https://eips.ethereum.org/EIPS/eip-165).
9 | *
10 | * Implementers can declare support of contract interfaces, which can then be
11 | * queried by others (`ERC165Checker`).
12 | *
13 | * For an implementation, see `ERC165`.
14 | */
15 | interface IERC165 {
16 | /**
17 | * @dev Returns true if this contract implements the interface defined by
18 | * `interfaceId`. See the corresponding
19 | * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
20 | * to learn more about how these ids are created.
21 | *
22 | * This function call must use less than 30 000 gas.
23 | */
24 | function supportsInterface(bytes4 interfaceId) external view returns (bool);
25 | }
26 |
27 | // File: @openzeppelin/contracts/token/ERC721/IERC721.sol
28 |
29 | pragma solidity ^0.5.0;
30 |
31 |
32 | /**
33 | * @dev Required interface of an ERC721 compliant contract.
34 | */
35 | contract IERC721 is IERC165 {
36 | event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
37 | event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
38 | event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
39 |
40 | /**
41 | * @dev Returns the number of NFTs in `owner`'s account.
42 | */
43 | function balanceOf(address owner) public view returns (uint256 balance);
44 |
45 | /**
46 | * @dev Returns the owner of the NFT specified by `tokenId`.
47 | */
48 | function ownerOf(uint256 tokenId) public view returns (address owner);
49 |
50 | /**
51 | * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
52 | * another (`to`).
53 | *
54 | *
55 | *
56 | * Requirements:
57 | * - `from`, `to` cannot be zero.
58 | * - `tokenId` must be owned by `from`.
59 | * - If the caller is not `from`, it must be have been allowed to move this
60 | * NFT by either `approve` or `setApproveForAll`.
61 | */
62 | function safeTransferFrom(address from, address to, uint256 tokenId) public;
63 | /**
64 | * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
65 | * another (`to`).
66 | *
67 | * Requirements:
68 | * - If the caller is not `from`, it must be approved to move this NFT by
69 | * either `approve` or `setApproveForAll`.
70 | */
71 | function transferFrom(address from, address to, uint256 tokenId) public;
72 | function approve(address to, uint256 tokenId) public;
73 | function getApproved(uint256 tokenId) public view returns (address operator);
74 |
75 | function setApprovalForAll(address operator, bool _approved) public;
76 | function isApprovedForAll(address owner, address operator) public view returns (bool);
77 |
78 |
79 | function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
80 | }
81 |
82 | // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
83 |
84 | pragma solidity ^0.5.0;
85 |
86 | /**
87 | * @title ERC721 token receiver interface
88 | * @dev Interface for any contract that wants to support safeTransfers
89 | * from ERC721 asset contracts.
90 | */
91 | contract IERC721Receiver {
92 | /**
93 | * @notice Handle the receipt of an NFT
94 | * @dev The ERC721 smart contract calls this function on the recipient
95 | * after a `safeTransfer`. This function MUST return the function selector,
96 | * otherwise the caller will revert the transaction. The selector to be
97 | * returned can be obtained as `this.onERC721Received.selector`. This
98 | * function MAY throw to revert and reject the transfer.
99 | * Note: the ERC721 contract address is always the message sender.
100 | * @param operator The address which called `safeTransferFrom` function
101 | * @param from The address which previously owned the token
102 | * @param tokenId The NFT identifier which is being transferred
103 | * @param data Additional data with no specified format
104 | * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
105 | */
106 | function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
107 | public returns (bytes4);
108 | }
109 |
110 | // File: @openzeppelin/contracts/math/SafeMath.sol
111 |
112 | pragma solidity ^0.5.0;
113 |
114 | /**
115 | * @dev Wrappers over Solidity's arithmetic operations with added overflow
116 | * checks.
117 | *
118 | * Arithmetic operations in Solidity wrap on overflow. This can easily result
119 | * in bugs, because programmers usually assume that an overflow raises an
120 | * error, which is the standard behavior in high level programming languages.
121 | * `SafeMath` restores this intuition by reverting the transaction when an
122 | * operation overflows.
123 | *
124 | * Using this library instead of the unchecked operations eliminates an entire
125 | * class of bugs, so it's recommended to use it always.
126 | */
127 | library SafeMath {
128 | /**
129 | * @dev Returns the addition of two unsigned integers, reverting on
130 | * overflow.
131 | *
132 | * Counterpart to Solidity's `+` operator.
133 | *
134 | * Requirements:
135 | * - Addition cannot overflow.
136 | */
137 | function add(uint256 a, uint256 b) internal pure returns (uint256) {
138 | uint256 c = a + b;
139 | require(c >= a, "SafeMath: addition overflow");
140 |
141 | return c;
142 | }
143 |
144 | /**
145 | * @dev Returns the subtraction of two unsigned integers, reverting on
146 | * overflow (when the result is negative).
147 | *
148 | * Counterpart to Solidity's `-` operator.
149 | *
150 | * Requirements:
151 | * - Subtraction cannot overflow.
152 | */
153 | function sub(uint256 a, uint256 b) internal pure returns (uint256) {
154 | require(b <= a, "SafeMath: subtraction overflow");
155 | uint256 c = a - b;
156 |
157 | return c;
158 | }
159 |
160 | /**
161 | * @dev Returns the multiplication of two unsigned integers, reverting on
162 | * overflow.
163 | *
164 | * Counterpart to Solidity's `*` operator.
165 | *
166 | * Requirements:
167 | * - Multiplication cannot overflow.
168 | */
169 | function mul(uint256 a, uint256 b) internal pure returns (uint256) {
170 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
171 | // benefit is lost if 'b' is also tested.
172 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
173 | if (a == 0) {
174 | return 0;
175 | }
176 |
177 | uint256 c = a * b;
178 | require(c / a == b, "SafeMath: multiplication overflow");
179 |
180 | return c;
181 | }
182 |
183 | /**
184 | * @dev Returns the integer division of two unsigned integers. Reverts on
185 | * division by zero. The result is rounded towards zero.
186 | *
187 | * Counterpart to Solidity's `/` operator. Note: this function uses a
188 | * `revert` opcode (which leaves remaining gas untouched) while Solidity
189 | * uses an invalid opcode to revert (consuming all remaining gas).
190 | *
191 | * Requirements:
192 | * - The divisor cannot be zero.
193 | */
194 | function div(uint256 a, uint256 b) internal pure returns (uint256) {
195 | // Solidity only automatically asserts when dividing by 0
196 | require(b > 0, "SafeMath: division by zero");
197 | uint256 c = a / b;
198 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold
199 |
200 | return c;
201 | }
202 |
203 | /**
204 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
205 | * Reverts when dividing by zero.
206 | *
207 | * Counterpart to Solidity's `%` operator. This function uses a `revert`
208 | * opcode (which leaves remaining gas untouched) while Solidity uses an
209 | * invalid opcode to revert (consuming all remaining gas).
210 | *
211 | * Requirements:
212 | * - The divisor cannot be zero.
213 | */
214 | function mod(uint256 a, uint256 b) internal pure returns (uint256) {
215 | require(b != 0, "SafeMath: modulo by zero");
216 | return a % b;
217 | }
218 | }
219 |
220 | // File: @openzeppelin/contracts/utils/Address.sol
221 |
222 | pragma solidity ^0.5.0;
223 |
224 | /**
225 | * @dev Collection of functions related to the address type,
226 | */
227 | library Address {
228 | /**
229 | * @dev Returns true if `account` is a contract.
230 | *
231 | * This test is non-exhaustive, and there may be false-negatives: during the
232 | * execution of a contract's constructor, its address will be reported as
233 | * not containing a contract.
234 | *
235 | * > It is unsafe to assume that an address for which this function returns
236 | * false is an externally-owned account (EOA) and not a contract.
237 | */
238 | function isContract(address account) internal view returns (bool) {
239 | // This method relies in extcodesize, which returns 0 for contracts in
240 | // construction, since the code is only stored at the end of the
241 | // constructor execution.
242 |
243 | uint256 size;
244 | // solhint-disable-next-line no-inline-assembly
245 | assembly { size := extcodesize(account) }
246 | return size > 0;
247 | }
248 | }
249 |
250 | // File: @openzeppelin/contracts/drafts/Counters.sol
251 |
252 | pragma solidity ^0.5.0;
253 |
254 |
255 | /**
256 | * @title Counters
257 | * @author Matt Condon (@shrugs)
258 | * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
259 | * of elements in a mapping, issuing ERC721 ids, or counting request ids.
260 | *
261 | * Include with `using Counters for Counters.Counter;`
262 | * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath
263 | * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
264 | * directly accessed.
265 | */
266 | library Counters {
267 | using SafeMath for uint256;
268 |
269 | struct Counter {
270 | // This variable should never be directly accessed by users of the library: interactions must be restricted to
271 | // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
272 | // this feature: see https://github.com/ethereum/solidity/issues/4637
273 | uint256 _value; // default: 0
274 | }
275 |
276 | function current(Counter storage counter) internal view returns (uint256) {
277 | return counter._value;
278 | }
279 |
280 | function increment(Counter storage counter) internal {
281 | counter._value += 1;
282 | }
283 |
284 | function decrement(Counter storage counter) internal {
285 | counter._value = counter._value.sub(1);
286 | }
287 | }
288 |
289 | // File: @openzeppelin/contracts/introspection/ERC165.sol
290 |
291 | pragma solidity ^0.5.0;
292 |
293 |
294 | /**
295 | * @dev Implementation of the `IERC165` interface.
296 | *
297 | * Contracts may inherit from this and call `_registerInterface` to declare
298 | * their support of an interface.
299 | */
300 | contract ERC165 is IERC165 {
301 | /*
302 | * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
303 | */
304 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
305 |
306 | /**
307 | * @dev Mapping of interface ids to whether or not it's supported.
308 | */
309 | mapping(bytes4 => bool) private _supportedInterfaces;
310 |
311 | constructor () internal {
312 | // Derived contracts need only register support for their own interfaces,
313 | // we register support for ERC165 itself here
314 | _registerInterface(_INTERFACE_ID_ERC165);
315 | }
316 |
317 | /**
318 | * @dev See `IERC165.supportsInterface`.
319 | *
320 | * Time complexity O(1), guaranteed to always use less than 30 000 gas.
321 | */
322 | function supportsInterface(bytes4 interfaceId) external view returns (bool) {
323 | return _supportedInterfaces[interfaceId];
324 | }
325 |
326 | /**
327 | * @dev Registers the contract as an implementer of the interface defined by
328 | * `interfaceId`. Support of the actual ERC165 interface is automatic and
329 | * registering its interface id is not required.
330 | *
331 | * See `IERC165.supportsInterface`.
332 | *
333 | * Requirements:
334 | *
335 | * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
336 | */
337 | function _registerInterface(bytes4 interfaceId) internal {
338 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
339 | _supportedInterfaces[interfaceId] = true;
340 | }
341 | }
342 |
343 | // File: @openzeppelin/contracts/token/ERC721/ERC721.sol
344 |
345 | pragma solidity ^0.5.0;
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 | /**
354 | * @title ERC721 Non-Fungible Token Standard basic implementation
355 | * @dev see https://eips.ethereum.org/EIPS/eip-721
356 | */
357 | contract ERC721 is ERC165, IERC721 {
358 | using SafeMath for uint256;
359 | using Address for address;
360 | using Counters for Counters.Counter;
361 |
362 | // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
363 | // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
364 | bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
365 |
366 | // Mapping from token ID to owner
367 | mapping (uint256 => address) private _tokenOwner;
368 |
369 | // Mapping from token ID to approved address
370 | mapping (uint256 => address) private _tokenApprovals;
371 |
372 | // Mapping from owner to number of owned token
373 | mapping (address => Counters.Counter) private _ownedTokensCount;
374 |
375 | // Mapping from owner to operator approvals
376 | mapping (address => mapping (address => bool)) private _operatorApprovals;
377 |
378 | /*
379 | * bytes4(keccak256('balanceOf(address)')) == 0x70a08231
380 | * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
381 | * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
382 | * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
383 | * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
384 | * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c
385 | * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
386 | * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
387 | * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
388 | *
389 | * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
390 | * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
391 | */
392 | bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
393 |
394 | constructor () public {
395 | // register the supported interfaces to conform to ERC721 via ERC165
396 | _registerInterface(_INTERFACE_ID_ERC721);
397 | }
398 |
399 | /**
400 | * @dev Gets the balance of the specified address.
401 | * @param owner address to query the balance of
402 | * @return uint256 representing the amount owned by the passed address
403 | */
404 | function balanceOf(address owner) public view returns (uint256) {
405 | require(owner != address(0), "ERC721: balance query for the zero address");
406 |
407 | return _ownedTokensCount[owner].current();
408 | }
409 |
410 | /**
411 | * @dev Gets the owner of the specified token ID.
412 | * @param tokenId uint256 ID of the token to query the owner of
413 | * @return address currently marked as the owner of the given token ID
414 | */
415 | function ownerOf(uint256 tokenId) public view returns (address) {
416 | address owner = _tokenOwner[tokenId];
417 | require(owner != address(0), "ERC721: owner query for nonexistent token");
418 |
419 | return owner;
420 | }
421 |
422 | /**
423 | * @dev Approves another address to transfer the given token ID
424 | * The zero address indicates there is no approved address.
425 | * There can only be one approved address per token at a given time.
426 | * Can only be called by the token owner or an approved operator.
427 | * @param to address to be approved for the given token ID
428 | * @param tokenId uint256 ID of the token to be approved
429 | */
430 | function approve(address to, uint256 tokenId) public {
431 | address owner = ownerOf(tokenId);
432 | require(to != owner, "ERC721: approval to current owner");
433 |
434 | require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
435 | "ERC721: approve caller is not owner nor approved for all"
436 | );
437 |
438 | _tokenApprovals[tokenId] = to;
439 | emit Approval(owner, to, tokenId);
440 | }
441 |
442 | /**
443 | * @dev Gets the approved address for a token ID, or zero if no address set
444 | * Reverts if the token ID does not exist.
445 | * @param tokenId uint256 ID of the token to query the approval of
446 | * @return address currently approved for the given token ID
447 | */
448 | function getApproved(uint256 tokenId) public view returns (address) {
449 | require(_exists(tokenId), "ERC721: approved query for nonexistent token");
450 |
451 | return _tokenApprovals[tokenId];
452 | }
453 |
454 | /**
455 | * @dev Sets or unsets the approval of a given operator
456 | * An operator is allowed to transfer all tokens of the sender on their behalf.
457 | * @param to operator address to set the approval
458 | * @param approved representing the status of the approval to be set
459 | */
460 | function setApprovalForAll(address to, bool approved) public {
461 | require(to != msg.sender, "ERC721: approve to caller");
462 |
463 | _operatorApprovals[msg.sender][to] = approved;
464 | emit ApprovalForAll(msg.sender, to, approved);
465 | }
466 |
467 | /**
468 | * @dev Tells whether an operator is approved by a given owner.
469 | * @param owner owner address which you want to query the approval of
470 | * @param operator operator address which you want to query the approval of
471 | * @return bool whether the given operator is approved by the given owner
472 | */
473 | function isApprovedForAll(address owner, address operator) public view returns (bool) {
474 | return _operatorApprovals[owner][operator];
475 | }
476 |
477 | /**
478 | * @dev Transfers the ownership of a given token ID to another address.
479 | * Usage of this method is discouraged, use `safeTransferFrom` whenever possible.
480 | * Requires the msg.sender to be the owner, approved, or operator.
481 | * @param from current owner of the token
482 | * @param to address to receive the ownership of the given token ID
483 | * @param tokenId uint256 ID of the token to be transferred
484 | */
485 | function transferFrom(address from, address to, uint256 tokenId) public {
486 | //solhint-disable-next-line max-line-length
487 | require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
488 |
489 | _transferFrom(from, to, tokenId);
490 | }
491 |
492 | /**
493 | * @dev Safely transfers the ownership of a given token ID to another address
494 | * If the target address is a contract, it must implement `onERC721Received`,
495 | * which is called upon a safe transfer, and return the magic value
496 | * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
497 | * the transfer is reverted.
498 | * Requires the msg.sender to be the owner, approved, or operator
499 | * @param from current owner of the token
500 | * @param to address to receive the ownership of the given token ID
501 | * @param tokenId uint256 ID of the token to be transferred
502 | */
503 | function safeTransferFrom(address from, address to, uint256 tokenId) public {
504 | safeTransferFrom(from, to, tokenId, "");
505 | }
506 |
507 | /**
508 | * @dev Safely transfers the ownership of a given token ID to another address
509 | * If the target address is a contract, it must implement `onERC721Received`,
510 | * which is called upon a safe transfer, and return the magic value
511 | * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
512 | * the transfer is reverted.
513 | * Requires the msg.sender to be the owner, approved, or operator
514 | * @param from current owner of the token
515 | * @param to address to receive the ownership of the given token ID
516 | * @param tokenId uint256 ID of the token to be transferred
517 | * @param _data bytes data to send along with a safe transfer check
518 | */
519 | function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
520 | transferFrom(from, to, tokenId);
521 | require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
522 | }
523 |
524 | /**
525 | * @dev Returns whether the specified token exists.
526 | * @param tokenId uint256 ID of the token to query the existence of
527 | * @return bool whether the token exists
528 | */
529 | function _exists(uint256 tokenId) internal view returns (bool) {
530 | address owner = _tokenOwner[tokenId];
531 | return owner != address(0);
532 | }
533 |
534 | /**
535 | * @dev Returns whether the given spender can transfer a given token ID.
536 | * @param spender address of the spender to query
537 | * @param tokenId uint256 ID of the token to be transferred
538 | * @return bool whether the msg.sender is approved for the given token ID,
539 | * is an operator of the owner, or is the owner of the token
540 | */
541 | function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
542 | require(_exists(tokenId), "ERC721: operator query for nonexistent token");
543 | address owner = ownerOf(tokenId);
544 | return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
545 | }
546 |
547 | /**
548 | * @dev Internal function to mint a new token.
549 | * Reverts if the given token ID already exists.
550 | * @param to The address that will own the minted token
551 | * @param tokenId uint256 ID of the token to be minted
552 | */
553 | function _mint(address to, uint256 tokenId) internal {
554 | require(to != address(0), "ERC721: mint to the zero address");
555 | require(!_exists(tokenId), "ERC721: token already minted");
556 |
557 | _tokenOwner[tokenId] = to;
558 | _ownedTokensCount[to].increment();
559 |
560 | emit Transfer(address(0), to, tokenId);
561 | }
562 |
563 | /**
564 | * @dev Internal function to burn a specific token.
565 | * Reverts if the token does not exist.
566 | * Deprecated, use _burn(uint256) instead.
567 | * @param owner owner of the token to burn
568 | * @param tokenId uint256 ID of the token being burned
569 | */
570 | function _burn(address owner, uint256 tokenId) internal {
571 | require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");
572 |
573 | _clearApproval(tokenId);
574 |
575 | _ownedTokensCount[owner].decrement();
576 | _tokenOwner[tokenId] = address(0);
577 |
578 | emit Transfer(owner, address(0), tokenId);
579 | }
580 |
581 | /**
582 | * @dev Internal function to burn a specific token.
583 | * Reverts if the token does not exist.
584 | * @param tokenId uint256 ID of the token being burned
585 | */
586 | function _burn(uint256 tokenId) internal {
587 | _burn(ownerOf(tokenId), tokenId);
588 | }
589 |
590 | /**
591 | * @dev Internal function to transfer ownership of a given token ID to another address.
592 | * As opposed to transferFrom, this imposes no restrictions on msg.sender.
593 | * @param from current owner of the token
594 | * @param to address to receive the ownership of the given token ID
595 | * @param tokenId uint256 ID of the token to be transferred
596 | */
597 | function _transferFrom(address from, address to, uint256 tokenId) internal {
598 | require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
599 | require(to != address(0), "ERC721: transfer to the zero address");
600 |
601 | _clearApproval(tokenId);
602 |
603 | _ownedTokensCount[from].decrement();
604 | _ownedTokensCount[to].increment();
605 |
606 | _tokenOwner[tokenId] = to;
607 |
608 | emit Transfer(from, to, tokenId);
609 | }
610 |
611 | /**
612 | * @dev Internal function to invoke `onERC721Received` on a target address.
613 | * The call is not executed if the target address is not a contract.
614 | *
615 | * This function is deprecated.
616 | * @param from address representing the previous owner of the given token ID
617 | * @param to target address that will receive the tokens
618 | * @param tokenId uint256 ID of the token to be transferred
619 | * @param _data bytes optional data to send along with the call
620 | * @return bool whether the call correctly returned the expected magic value
621 | */
622 | function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
623 | internal returns (bool)
624 | {
625 | if (!to.isContract()) {
626 | return true;
627 | }
628 |
629 | bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data);
630 | return (retval == _ERC721_RECEIVED);
631 | }
632 |
633 | /**
634 | * @dev Private function to clear current approval of a given token ID.
635 | * @param tokenId uint256 ID of the token to be transferred
636 | */
637 | function _clearApproval(uint256 tokenId) private {
638 | if (_tokenApprovals[tokenId] != address(0)) {
639 | _tokenApprovals[tokenId] = address(0);
640 | }
641 | }
642 | }
643 |
644 | // File: @openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol
645 |
646 | pragma solidity ^0.5.0;
647 |
648 |
649 | /**
650 | * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
651 | * @dev See https://eips.ethereum.org/EIPS/eip-721
652 | */
653 | contract IERC721Enumerable is IERC721 {
654 | function totalSupply() public view returns (uint256);
655 | function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);
656 |
657 | function tokenByIndex(uint256 index) public view returns (uint256);
658 | }
659 |
660 | // File: @openzeppelin/contracts/token/ERC721/ERC721Enumerable.sol
661 |
662 | pragma solidity ^0.5.0;
663 |
664 |
665 |
666 |
667 | /**
668 | * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
669 | * @dev See https://eips.ethereum.org/EIPS/eip-721
670 | */
671 | contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable {
672 | // Mapping from owner to list of owned token IDs
673 | mapping(address => uint256[]) private _ownedTokens;
674 |
675 | // Mapping from token ID to index of the owner tokens list
676 | mapping(uint256 => uint256) private _ownedTokensIndex;
677 |
678 | // Array with all token ids, used for enumeration
679 | uint256[] private _allTokens;
680 |
681 | // Mapping from token id to position in the allTokens array
682 | mapping(uint256 => uint256) private _allTokensIndex;
683 |
684 | /*
685 | * bytes4(keccak256('totalSupply()')) == 0x18160ddd
686 | * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
687 | * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
688 | *
689 | * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
690 | */
691 | bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
692 |
693 | /**
694 | * @dev Constructor function.
695 | */
696 | constructor () public {
697 | // register the supported interface to conform to ERC721Enumerable via ERC165
698 | _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
699 | }
700 |
701 | /**
702 | * @dev Gets the token ID at a given index of the tokens list of the requested owner.
703 | * @param owner address owning the tokens list to be accessed
704 | * @param index uint256 representing the index to be accessed of the requested tokens list
705 | * @return uint256 token ID at the given index of the tokens list owned by the requested address
706 | */
707 | function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
708 | require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
709 | return _ownedTokens[owner][index];
710 | }
711 |
712 | /**
713 | * @dev Gets the total amount of tokens stored by the contract.
714 | * @return uint256 representing the total amount of tokens
715 | */
716 | function totalSupply() public view returns (uint256) {
717 | return _allTokens.length;
718 | }
719 |
720 | /**
721 | * @dev Gets the token ID at a given index of all the tokens in this contract
722 | * Reverts if the index is greater or equal to the total number of tokens.
723 | * @param index uint256 representing the index to be accessed of the tokens list
724 | * @return uint256 token ID at the given index of the tokens list
725 | */
726 | function tokenByIndex(uint256 index) public view returns (uint256) {
727 | require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
728 | return _allTokens[index];
729 | }
730 |
731 | /**
732 | * @dev Internal function to transfer ownership of a given token ID to another address.
733 | * As opposed to transferFrom, this imposes no restrictions on msg.sender.
734 | * @param from current owner of the token
735 | * @param to address to receive the ownership of the given token ID
736 | * @param tokenId uint256 ID of the token to be transferred
737 | */
738 | function _transferFrom(address from, address to, uint256 tokenId) internal {
739 | super._transferFrom(from, to, tokenId);
740 |
741 | _removeTokenFromOwnerEnumeration(from, tokenId);
742 |
743 | _addTokenToOwnerEnumeration(to, tokenId);
744 | }
745 |
746 | /**
747 | * @dev Internal function to mint a new token.
748 | * Reverts if the given token ID already exists.
749 | * @param to address the beneficiary that will own the minted token
750 | * @param tokenId uint256 ID of the token to be minted
751 | */
752 | function _mint(address to, uint256 tokenId) internal {
753 | super._mint(to, tokenId);
754 |
755 | _addTokenToOwnerEnumeration(to, tokenId);
756 |
757 | _addTokenToAllTokensEnumeration(tokenId);
758 | }
759 |
760 | /**
761 | * @dev Internal function to burn a specific token.
762 | * Reverts if the token does not exist.
763 | * Deprecated, use _burn(uint256) instead.
764 | * @param owner owner of the token to burn
765 | * @param tokenId uint256 ID of the token being burned
766 | */
767 | function _burn(address owner, uint256 tokenId) internal {
768 | super._burn(owner, tokenId);
769 |
770 | _removeTokenFromOwnerEnumeration(owner, tokenId);
771 | // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
772 | _ownedTokensIndex[tokenId] = 0;
773 |
774 | _removeTokenFromAllTokensEnumeration(tokenId);
775 | }
776 |
777 | /**
778 | * @dev Gets the list of token IDs of the requested owner.
779 | * @param owner address owning the tokens
780 | * @return uint256[] List of token IDs owned by the requested address
781 | */
782 | function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
783 | return _ownedTokens[owner];
784 | }
785 |
786 | /**
787 | * @dev Private function to add a token to this extension's ownership-tracking data structures.
788 | * @param to address representing the new owner of the given token ID
789 | * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
790 | */
791 | function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
792 | _ownedTokensIndex[tokenId] = _ownedTokens[to].length;
793 | _ownedTokens[to].push(tokenId);
794 | }
795 |
796 | /**
797 | * @dev Private function to add a token to this extension's token tracking data structures.
798 | * @param tokenId uint256 ID of the token to be added to the tokens list
799 | */
800 | function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
801 | _allTokensIndex[tokenId] = _allTokens.length;
802 | _allTokens.push(tokenId);
803 | }
804 |
805 | /**
806 | * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
807 | * while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for
808 | * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
809 | * This has O(1) time complexity, but alters the order of the _ownedTokens array.
810 | * @param from address representing the previous owner of the given token ID
811 | * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
812 | */
813 | function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
814 | // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
815 | // then delete the last slot (swap and pop).
816 |
817 | uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
818 | uint256 tokenIndex = _ownedTokensIndex[tokenId];
819 |
820 | // When the token to delete is the last token, the swap operation is unnecessary
821 | if (tokenIndex != lastTokenIndex) {
822 | uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
823 |
824 | _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
825 | _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
826 | }
827 |
828 | // This also deletes the contents at the last position of the array
829 | _ownedTokens[from].length--;
830 |
831 | // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
832 | // lastTokenId, or just over the end of the array if the token was the last one).
833 | }
834 |
835 | /**
836 | * @dev Private function to remove a token from this extension's token tracking data structures.
837 | * This has O(1) time complexity, but alters the order of the _allTokens array.
838 | * @param tokenId uint256 ID of the token to be removed from the tokens list
839 | */
840 | function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
841 | // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
842 | // then delete the last slot (swap and pop).
843 |
844 | uint256 lastTokenIndex = _allTokens.length.sub(1);
845 | uint256 tokenIndex = _allTokensIndex[tokenId];
846 |
847 | // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
848 | // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
849 | // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
850 | uint256 lastTokenId = _allTokens[lastTokenIndex];
851 |
852 | _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
853 | _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
854 |
855 | // This also deletes the contents at the last position of the array
856 | _allTokens.length--;
857 | _allTokensIndex[tokenId] = 0;
858 | }
859 | }
860 |
861 | // File: @openzeppelin/contracts/token/ERC721/IERC721Metadata.sol
862 |
863 | pragma solidity ^0.5.0;
864 |
865 |
866 | /**
867 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
868 | * @dev See https://eips.ethereum.org/EIPS/eip-721
869 | */
870 | contract IERC721Metadata is IERC721 {
871 | function name() external view returns (string memory);
872 | function symbol() external view returns (string memory);
873 | function tokenURI(uint256 tokenId) external view returns (string memory);
874 | }
875 |
876 | // File: @openzeppelin/contracts/token/ERC721/ERC721Metadata.sol
877 |
878 | pragma solidity ^0.5.0;
879 |
880 |
881 |
882 |
883 | contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
884 | // Token name
885 | string private _name;
886 |
887 | // Token symbol
888 | string private _symbol;
889 |
890 | // Optional mapping for token URIs
891 | mapping(uint256 => string) private _tokenURIs;
892 |
893 | /*
894 | * bytes4(keccak256('name()')) == 0x06fdde03
895 | * bytes4(keccak256('symbol()')) == 0x95d89b41
896 | * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
897 | *
898 | * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
899 | */
900 | bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
901 |
902 | /**
903 | * @dev Constructor function
904 | */
905 | constructor (string memory name, string memory symbol) public {
906 | _name = name;
907 | _symbol = symbol;
908 |
909 | // register the supported interfaces to conform to ERC721 via ERC165
910 | _registerInterface(_INTERFACE_ID_ERC721_METADATA);
911 | }
912 |
913 | /**
914 | * @dev Gets the token name.
915 | * @return string representing the token name
916 | */
917 | function name() external view returns (string memory) {
918 | return _name;
919 | }
920 |
921 | /**
922 | * @dev Gets the token symbol.
923 | * @return string representing the token symbol
924 | */
925 | function symbol() external view returns (string memory) {
926 | return _symbol;
927 | }
928 |
929 | /**
930 | * @dev Returns an URI for a given token ID.
931 | * Throws if the token ID does not exist. May return an empty string.
932 | * @param tokenId uint256 ID of the token to query
933 | */
934 | function tokenURI(uint256 tokenId) external view returns (string memory) {
935 | require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
936 | return _tokenURIs[tokenId];
937 | }
938 |
939 | /**
940 | * @dev Internal function to set the token URI for a given token.
941 | * Reverts if the token ID does not exist.
942 | * @param tokenId uint256 ID of the token to set its URI
943 | * @param uri string URI to assign
944 | */
945 | function _setTokenURI(uint256 tokenId, string memory uri) internal {
946 | require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
947 | _tokenURIs[tokenId] = uri;
948 | }
949 |
950 | /**
951 | * @dev Internal function to burn a specific token.
952 | * Reverts if the token does not exist.
953 | * Deprecated, use _burn(uint256) instead.
954 | * @param owner owner of the token to burn
955 | * @param tokenId uint256 ID of the token being burned by the msg.sender
956 | */
957 | function _burn(address owner, uint256 tokenId) internal {
958 | super._burn(owner, tokenId);
959 |
960 | // Clear metadata (if any)
961 | if (bytes(_tokenURIs[tokenId]).length != 0) {
962 | delete _tokenURIs[tokenId];
963 | }
964 | }
965 | }
966 |
967 | // File: @openzeppelin/contracts/token/ERC721/ERC721Full.sol
968 |
969 | pragma solidity ^0.5.0;
970 |
971 |
972 |
973 |
974 | /**
975 | * @title Full ERC721 Token
976 | * This implementation includes all the required and some optional functionality of the ERC721 standard
977 | * Moreover, it includes approve all functionality using operator terminology
978 | * @dev see https://eips.ethereum.org/EIPS/eip-721
979 | */
980 | contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {
981 | constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) {
982 | // solhint-disable-previous-line no-empty-blocks
983 | }
984 | }
985 |
--------------------------------------------------------------------------------
/src/abis/Migrations.json:
--------------------------------------------------------------------------------
1 | {
2 | "contractName": "Migrations",
3 | "abi": [
4 | {
5 | "constant": true,
6 | "inputs": [],
7 | "name": "last_completed_migration",
8 | "outputs": [
9 | {
10 | "name": "",
11 | "type": "uint256"
12 | }
13 | ],
14 | "payable": false,
15 | "stateMutability": "view",
16 | "type": "function"
17 | },
18 | {
19 | "constant": true,
20 | "inputs": [],
21 | "name": "owner",
22 | "outputs": [
23 | {
24 | "name": "",
25 | "type": "address"
26 | }
27 | ],
28 | "payable": false,
29 | "stateMutability": "view",
30 | "type": "function"
31 | },
32 | {
33 | "inputs": [],
34 | "payable": false,
35 | "stateMutability": "nonpayable",
36 | "type": "constructor"
37 | },
38 | {
39 | "constant": false,
40 | "inputs": [
41 | {
42 | "name": "completed",
43 | "type": "uint256"
44 | }
45 | ],
46 | "name": "setCompleted",
47 | "outputs": [],
48 | "payable": false,
49 | "stateMutability": "nonpayable",
50 | "type": "function"
51 | },
52 | {
53 | "constant": false,
54 | "inputs": [
55 | {
56 | "name": "new_address",
57 | "type": "address"
58 | }
59 | ],
60 | "name": "upgrade",
61 | "outputs": [],
62 | "payable": false,
63 | "stateMutability": "nonpayable",
64 | "type": "function"
65 | }
66 | ],
67 | "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610314806100606000396000f3fe608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100b85780638da5cb5b146100e3578063fdacd5761461013a575b600080fd5b34801561007357600080fd5b506100b66004803603602081101561008a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610175565b005b3480156100c457600080fd5b506100cd61025d565b6040518082815260200191505060405180910390f35b3480156100ef57600080fd5b506100f8610263565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561014657600080fd5b506101736004803603602081101561015d57600080fd5b8101908080359060200190929190505050610288565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025a5760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561024057600080fd5b505af1158015610254573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102e557806001819055505b5056fea165627a7a723058202b7e0c14417bd38e7dc80df74a35483349341f9231414704022495630d81b2cf0029",
68 | "deployedBytecode": "0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100b85780638da5cb5b146100e3578063fdacd5761461013a575b600080fd5b34801561007357600080fd5b506100b66004803603602081101561008a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610175565b005b3480156100c457600080fd5b506100cd61025d565b6040518082815260200191505060405180910390f35b3480156100ef57600080fd5b506100f8610263565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561014657600080fd5b506101736004803603602081101561015d57600080fd5b8101908080359060200190929190505050610288565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561025a5760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561024057600080fd5b505af1158015610254573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102e557806001819055505b5056fea165627a7a723058202b7e0c14417bd38e7dc80df74a35483349341f9231414704022495630d81b2cf0029",
69 | "sourceMap": "34:480:2:-;;;123:50;8:9:-1;5:2;;;30:1;27;20:12;5:2;123:50:2;158:10;150:5;;:18;;;;;;;;;;;;;;;;;;34:480;;;;;;",
70 | "deployedSourceMap": "34:480:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;;8:9:-1;5:2;;;30:1;27;20:12;5:2;347:165:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;347:165:2;;;;;;;;;;;;;;;;;;;;;;82:36;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82:36:2;;;;;;;;;;;;;;;;;;;;;;;58:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58:20:2;;;;;;;;;;;;;;;;;;;;;;;;;;;240:103;;8:9:-1;5:2;;;30:1;27;20:12;5:2;240:103:2;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;240:103:2;;;;;;;;;;;;;;;;;;;;347:165;223:5;;;;;;;;;;;209:19;;:10;:19;;;205:26;;;409:19;442:11;409:45;;460:8;:21;;;482:24;;460:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;460:47:2;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;460:47:2;;;;230:1;205:26;347:165;:::o;82:36::-;;;;:::o;58:20::-;;;;;;;;;;;;;:::o;240:103::-;223:5;;;;;;;;;;;209:19;;:10;:19;;;205:26;;;329:9;302:24;:36;;;;205:26;240:103;:::o",
71 | "source": "pragma solidity >=0.4.21 <0.6.0;\n\ncontract Migrations {\n address public owner;\n uint public last_completed_migration;\n\n constructor() public {\n owner = msg.sender;\n }\n\n modifier restricted() {\n if (msg.sender == owner) _;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n\n function upgrade(address new_address) public restricted {\n Migrations upgraded = Migrations(new_address);\n upgraded.setCompleted(last_completed_migration);\n }\n}\n",
72 | "sourcePath": "/Users/gregory/code/nft/src/contracts/Migrations.sol",
73 | "ast": {
74 | "absolutePath": "/Users/gregory/code/nft/src/contracts/Migrations.sol",
75 | "exportedSymbols": {
76 | "Migrations": [
77 | 1525
78 | ]
79 | },
80 | "id": 1526,
81 | "nodeType": "SourceUnit",
82 | "nodes": [
83 | {
84 | "id": 1470,
85 | "literals": [
86 | "solidity",
87 | ">=",
88 | "0.4",
89 | ".21",
90 | "<",
91 | "0.6",
92 | ".0"
93 | ],
94 | "nodeType": "PragmaDirective",
95 | "src": "0:32:2"
96 | },
97 | {
98 | "baseContracts": [],
99 | "contractDependencies": [],
100 | "contractKind": "contract",
101 | "documentation": null,
102 | "fullyImplemented": true,
103 | "id": 1525,
104 | "linearizedBaseContracts": [
105 | 1525
106 | ],
107 | "name": "Migrations",
108 | "nodeType": "ContractDefinition",
109 | "nodes": [
110 | {
111 | "constant": false,
112 | "id": 1472,
113 | "name": "owner",
114 | "nodeType": "VariableDeclaration",
115 | "scope": 1525,
116 | "src": "58:20:2",
117 | "stateVariable": true,
118 | "storageLocation": "default",
119 | "typeDescriptions": {
120 | "typeIdentifier": "t_address",
121 | "typeString": "address"
122 | },
123 | "typeName": {
124 | "id": 1471,
125 | "name": "address",
126 | "nodeType": "ElementaryTypeName",
127 | "src": "58:7:2",
128 | "stateMutability": "nonpayable",
129 | "typeDescriptions": {
130 | "typeIdentifier": "t_address",
131 | "typeString": "address"
132 | }
133 | },
134 | "value": null,
135 | "visibility": "public"
136 | },
137 | {
138 | "constant": false,
139 | "id": 1474,
140 | "name": "last_completed_migration",
141 | "nodeType": "VariableDeclaration",
142 | "scope": 1525,
143 | "src": "82:36:2",
144 | "stateVariable": true,
145 | "storageLocation": "default",
146 | "typeDescriptions": {
147 | "typeIdentifier": "t_uint256",
148 | "typeString": "uint256"
149 | },
150 | "typeName": {
151 | "id": 1473,
152 | "name": "uint",
153 | "nodeType": "ElementaryTypeName",
154 | "src": "82:4:2",
155 | "typeDescriptions": {
156 | "typeIdentifier": "t_uint256",
157 | "typeString": "uint256"
158 | }
159 | },
160 | "value": null,
161 | "visibility": "public"
162 | },
163 | {
164 | "body": {
165 | "id": 1482,
166 | "nodeType": "Block",
167 | "src": "144:29:2",
168 | "statements": [
169 | {
170 | "expression": {
171 | "argumentTypes": null,
172 | "id": 1480,
173 | "isConstant": false,
174 | "isLValue": false,
175 | "isPure": false,
176 | "lValueRequested": false,
177 | "leftHandSide": {
178 | "argumentTypes": null,
179 | "id": 1477,
180 | "name": "owner",
181 | "nodeType": "Identifier",
182 | "overloadedDeclarations": [],
183 | "referencedDeclaration": 1472,
184 | "src": "150:5:2",
185 | "typeDescriptions": {
186 | "typeIdentifier": "t_address",
187 | "typeString": "address"
188 | }
189 | },
190 | "nodeType": "Assignment",
191 | "operator": "=",
192 | "rightHandSide": {
193 | "argumentTypes": null,
194 | "expression": {
195 | "argumentTypes": null,
196 | "id": 1478,
197 | "name": "msg",
198 | "nodeType": "Identifier",
199 | "overloadedDeclarations": [],
200 | "referencedDeclaration": 1540,
201 | "src": "158:3:2",
202 | "typeDescriptions": {
203 | "typeIdentifier": "t_magic_message",
204 | "typeString": "msg"
205 | }
206 | },
207 | "id": 1479,
208 | "isConstant": false,
209 | "isLValue": false,
210 | "isPure": false,
211 | "lValueRequested": false,
212 | "memberName": "sender",
213 | "nodeType": "MemberAccess",
214 | "referencedDeclaration": null,
215 | "src": "158:10:2",
216 | "typeDescriptions": {
217 | "typeIdentifier": "t_address_payable",
218 | "typeString": "address payable"
219 | }
220 | },
221 | "src": "150:18:2",
222 | "typeDescriptions": {
223 | "typeIdentifier": "t_address",
224 | "typeString": "address"
225 | }
226 | },
227 | "id": 1481,
228 | "nodeType": "ExpressionStatement",
229 | "src": "150:18:2"
230 | }
231 | ]
232 | },
233 | "documentation": null,
234 | "id": 1483,
235 | "implemented": true,
236 | "kind": "constructor",
237 | "modifiers": [],
238 | "name": "",
239 | "nodeType": "FunctionDefinition",
240 | "parameters": {
241 | "id": 1475,
242 | "nodeType": "ParameterList",
243 | "parameters": [],
244 | "src": "134:2:2"
245 | },
246 | "returnParameters": {
247 | "id": 1476,
248 | "nodeType": "ParameterList",
249 | "parameters": [],
250 | "src": "144:0:2"
251 | },
252 | "scope": 1525,
253 | "src": "123:50:2",
254 | "stateMutability": "nonpayable",
255 | "superFunction": null,
256 | "visibility": "public"
257 | },
258 | {
259 | "body": {
260 | "id": 1491,
261 | "nodeType": "Block",
262 | "src": "199:37:2",
263 | "statements": [
264 | {
265 | "condition": {
266 | "argumentTypes": null,
267 | "commonType": {
268 | "typeIdentifier": "t_address",
269 | "typeString": "address"
270 | },
271 | "id": 1488,
272 | "isConstant": false,
273 | "isLValue": false,
274 | "isPure": false,
275 | "lValueRequested": false,
276 | "leftExpression": {
277 | "argumentTypes": null,
278 | "expression": {
279 | "argumentTypes": null,
280 | "id": 1485,
281 | "name": "msg",
282 | "nodeType": "Identifier",
283 | "overloadedDeclarations": [],
284 | "referencedDeclaration": 1540,
285 | "src": "209:3:2",
286 | "typeDescriptions": {
287 | "typeIdentifier": "t_magic_message",
288 | "typeString": "msg"
289 | }
290 | },
291 | "id": 1486,
292 | "isConstant": false,
293 | "isLValue": false,
294 | "isPure": false,
295 | "lValueRequested": false,
296 | "memberName": "sender",
297 | "nodeType": "MemberAccess",
298 | "referencedDeclaration": null,
299 | "src": "209:10:2",
300 | "typeDescriptions": {
301 | "typeIdentifier": "t_address_payable",
302 | "typeString": "address payable"
303 | }
304 | },
305 | "nodeType": "BinaryOperation",
306 | "operator": "==",
307 | "rightExpression": {
308 | "argumentTypes": null,
309 | "id": 1487,
310 | "name": "owner",
311 | "nodeType": "Identifier",
312 | "overloadedDeclarations": [],
313 | "referencedDeclaration": 1472,
314 | "src": "223:5:2",
315 | "typeDescriptions": {
316 | "typeIdentifier": "t_address",
317 | "typeString": "address"
318 | }
319 | },
320 | "src": "209:19:2",
321 | "typeDescriptions": {
322 | "typeIdentifier": "t_bool",
323 | "typeString": "bool"
324 | }
325 | },
326 | "falseBody": null,
327 | "id": 1490,
328 | "nodeType": "IfStatement",
329 | "src": "205:26:2",
330 | "trueBody": {
331 | "id": 1489,
332 | "nodeType": "PlaceholderStatement",
333 | "src": "230:1:2"
334 | }
335 | }
336 | ]
337 | },
338 | "documentation": null,
339 | "id": 1492,
340 | "name": "restricted",
341 | "nodeType": "ModifierDefinition",
342 | "parameters": {
343 | "id": 1484,
344 | "nodeType": "ParameterList",
345 | "parameters": [],
346 | "src": "196:2:2"
347 | },
348 | "src": "177:59:2",
349 | "visibility": "internal"
350 | },
351 | {
352 | "body": {
353 | "id": 1503,
354 | "nodeType": "Block",
355 | "src": "296:47:2",
356 | "statements": [
357 | {
358 | "expression": {
359 | "argumentTypes": null,
360 | "id": 1501,
361 | "isConstant": false,
362 | "isLValue": false,
363 | "isPure": false,
364 | "lValueRequested": false,
365 | "leftHandSide": {
366 | "argumentTypes": null,
367 | "id": 1499,
368 | "name": "last_completed_migration",
369 | "nodeType": "Identifier",
370 | "overloadedDeclarations": [],
371 | "referencedDeclaration": 1474,
372 | "src": "302:24:2",
373 | "typeDescriptions": {
374 | "typeIdentifier": "t_uint256",
375 | "typeString": "uint256"
376 | }
377 | },
378 | "nodeType": "Assignment",
379 | "operator": "=",
380 | "rightHandSide": {
381 | "argumentTypes": null,
382 | "id": 1500,
383 | "name": "completed",
384 | "nodeType": "Identifier",
385 | "overloadedDeclarations": [],
386 | "referencedDeclaration": 1494,
387 | "src": "329:9:2",
388 | "typeDescriptions": {
389 | "typeIdentifier": "t_uint256",
390 | "typeString": "uint256"
391 | }
392 | },
393 | "src": "302:36:2",
394 | "typeDescriptions": {
395 | "typeIdentifier": "t_uint256",
396 | "typeString": "uint256"
397 | }
398 | },
399 | "id": 1502,
400 | "nodeType": "ExpressionStatement",
401 | "src": "302:36:2"
402 | }
403 | ]
404 | },
405 | "documentation": null,
406 | "id": 1504,
407 | "implemented": true,
408 | "kind": "function",
409 | "modifiers": [
410 | {
411 | "arguments": null,
412 | "id": 1497,
413 | "modifierName": {
414 | "argumentTypes": null,
415 | "id": 1496,
416 | "name": "restricted",
417 | "nodeType": "Identifier",
418 | "overloadedDeclarations": [],
419 | "referencedDeclaration": 1492,
420 | "src": "285:10:2",
421 | "typeDescriptions": {
422 | "typeIdentifier": "t_modifier$__$",
423 | "typeString": "modifier ()"
424 | }
425 | },
426 | "nodeType": "ModifierInvocation",
427 | "src": "285:10:2"
428 | }
429 | ],
430 | "name": "setCompleted",
431 | "nodeType": "FunctionDefinition",
432 | "parameters": {
433 | "id": 1495,
434 | "nodeType": "ParameterList",
435 | "parameters": [
436 | {
437 | "constant": false,
438 | "id": 1494,
439 | "name": "completed",
440 | "nodeType": "VariableDeclaration",
441 | "scope": 1504,
442 | "src": "262:14:2",
443 | "stateVariable": false,
444 | "storageLocation": "default",
445 | "typeDescriptions": {
446 | "typeIdentifier": "t_uint256",
447 | "typeString": "uint256"
448 | },
449 | "typeName": {
450 | "id": 1493,
451 | "name": "uint",
452 | "nodeType": "ElementaryTypeName",
453 | "src": "262:4:2",
454 | "typeDescriptions": {
455 | "typeIdentifier": "t_uint256",
456 | "typeString": "uint256"
457 | }
458 | },
459 | "value": null,
460 | "visibility": "internal"
461 | }
462 | ],
463 | "src": "261:16:2"
464 | },
465 | "returnParameters": {
466 | "id": 1498,
467 | "nodeType": "ParameterList",
468 | "parameters": [],
469 | "src": "296:0:2"
470 | },
471 | "scope": 1525,
472 | "src": "240:103:2",
473 | "stateMutability": "nonpayable",
474 | "superFunction": null,
475 | "visibility": "public"
476 | },
477 | {
478 | "body": {
479 | "id": 1523,
480 | "nodeType": "Block",
481 | "src": "403:109:2",
482 | "statements": [
483 | {
484 | "assignments": [
485 | 1512
486 | ],
487 | "declarations": [
488 | {
489 | "constant": false,
490 | "id": 1512,
491 | "name": "upgraded",
492 | "nodeType": "VariableDeclaration",
493 | "scope": 1523,
494 | "src": "409:19:2",
495 | "stateVariable": false,
496 | "storageLocation": "default",
497 | "typeDescriptions": {
498 | "typeIdentifier": "t_contract$_Migrations_$1525",
499 | "typeString": "contract Migrations"
500 | },
501 | "typeName": {
502 | "contractScope": null,
503 | "id": 1511,
504 | "name": "Migrations",
505 | "nodeType": "UserDefinedTypeName",
506 | "referencedDeclaration": 1525,
507 | "src": "409:10:2",
508 | "typeDescriptions": {
509 | "typeIdentifier": "t_contract$_Migrations_$1525",
510 | "typeString": "contract Migrations"
511 | }
512 | },
513 | "value": null,
514 | "visibility": "internal"
515 | }
516 | ],
517 | "id": 1516,
518 | "initialValue": {
519 | "argumentTypes": null,
520 | "arguments": [
521 | {
522 | "argumentTypes": null,
523 | "id": 1514,
524 | "name": "new_address",
525 | "nodeType": "Identifier",
526 | "overloadedDeclarations": [],
527 | "referencedDeclaration": 1506,
528 | "src": "442:11:2",
529 | "typeDescriptions": {
530 | "typeIdentifier": "t_address",
531 | "typeString": "address"
532 | }
533 | }
534 | ],
535 | "expression": {
536 | "argumentTypes": [
537 | {
538 | "typeIdentifier": "t_address",
539 | "typeString": "address"
540 | }
541 | ],
542 | "id": 1513,
543 | "name": "Migrations",
544 | "nodeType": "Identifier",
545 | "overloadedDeclarations": [],
546 | "referencedDeclaration": 1525,
547 | "src": "431:10:2",
548 | "typeDescriptions": {
549 | "typeIdentifier": "t_type$_t_contract$_Migrations_$1525_$",
550 | "typeString": "type(contract Migrations)"
551 | }
552 | },
553 | "id": 1515,
554 | "isConstant": false,
555 | "isLValue": false,
556 | "isPure": false,
557 | "kind": "typeConversion",
558 | "lValueRequested": false,
559 | "names": [],
560 | "nodeType": "FunctionCall",
561 | "src": "431:23:2",
562 | "typeDescriptions": {
563 | "typeIdentifier": "t_contract$_Migrations_$1525",
564 | "typeString": "contract Migrations"
565 | }
566 | },
567 | "nodeType": "VariableDeclarationStatement",
568 | "src": "409:45:2"
569 | },
570 | {
571 | "expression": {
572 | "argumentTypes": null,
573 | "arguments": [
574 | {
575 | "argumentTypes": null,
576 | "id": 1520,
577 | "name": "last_completed_migration",
578 | "nodeType": "Identifier",
579 | "overloadedDeclarations": [],
580 | "referencedDeclaration": 1474,
581 | "src": "482:24:2",
582 | "typeDescriptions": {
583 | "typeIdentifier": "t_uint256",
584 | "typeString": "uint256"
585 | }
586 | }
587 | ],
588 | "expression": {
589 | "argumentTypes": [
590 | {
591 | "typeIdentifier": "t_uint256",
592 | "typeString": "uint256"
593 | }
594 | ],
595 | "expression": {
596 | "argumentTypes": null,
597 | "id": 1517,
598 | "name": "upgraded",
599 | "nodeType": "Identifier",
600 | "overloadedDeclarations": [],
601 | "referencedDeclaration": 1512,
602 | "src": "460:8:2",
603 | "typeDescriptions": {
604 | "typeIdentifier": "t_contract$_Migrations_$1525",
605 | "typeString": "contract Migrations"
606 | }
607 | },
608 | "id": 1519,
609 | "isConstant": false,
610 | "isLValue": false,
611 | "isPure": false,
612 | "lValueRequested": false,
613 | "memberName": "setCompleted",
614 | "nodeType": "MemberAccess",
615 | "referencedDeclaration": 1504,
616 | "src": "460:21:2",
617 | "typeDescriptions": {
618 | "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$",
619 | "typeString": "function (uint256) external"
620 | }
621 | },
622 | "id": 1521,
623 | "isConstant": false,
624 | "isLValue": false,
625 | "isPure": false,
626 | "kind": "functionCall",
627 | "lValueRequested": false,
628 | "names": [],
629 | "nodeType": "FunctionCall",
630 | "src": "460:47:2",
631 | "typeDescriptions": {
632 | "typeIdentifier": "t_tuple$__$",
633 | "typeString": "tuple()"
634 | }
635 | },
636 | "id": 1522,
637 | "nodeType": "ExpressionStatement",
638 | "src": "460:47:2"
639 | }
640 | ]
641 | },
642 | "documentation": null,
643 | "id": 1524,
644 | "implemented": true,
645 | "kind": "function",
646 | "modifiers": [
647 | {
648 | "arguments": null,
649 | "id": 1509,
650 | "modifierName": {
651 | "argumentTypes": null,
652 | "id": 1508,
653 | "name": "restricted",
654 | "nodeType": "Identifier",
655 | "overloadedDeclarations": [],
656 | "referencedDeclaration": 1492,
657 | "src": "392:10:2",
658 | "typeDescriptions": {
659 | "typeIdentifier": "t_modifier$__$",
660 | "typeString": "modifier ()"
661 | }
662 | },
663 | "nodeType": "ModifierInvocation",
664 | "src": "392:10:2"
665 | }
666 | ],
667 | "name": "upgrade",
668 | "nodeType": "FunctionDefinition",
669 | "parameters": {
670 | "id": 1507,
671 | "nodeType": "ParameterList",
672 | "parameters": [
673 | {
674 | "constant": false,
675 | "id": 1506,
676 | "name": "new_address",
677 | "nodeType": "VariableDeclaration",
678 | "scope": 1524,
679 | "src": "364:19:2",
680 | "stateVariable": false,
681 | "storageLocation": "default",
682 | "typeDescriptions": {
683 | "typeIdentifier": "t_address",
684 | "typeString": "address"
685 | },
686 | "typeName": {
687 | "id": 1505,
688 | "name": "address",
689 | "nodeType": "ElementaryTypeName",
690 | "src": "364:7:2",
691 | "stateMutability": "nonpayable",
692 | "typeDescriptions": {
693 | "typeIdentifier": "t_address",
694 | "typeString": "address"
695 | }
696 | },
697 | "value": null,
698 | "visibility": "internal"
699 | }
700 | ],
701 | "src": "363:21:2"
702 | },
703 | "returnParameters": {
704 | "id": 1510,
705 | "nodeType": "ParameterList",
706 | "parameters": [],
707 | "src": "403:0:2"
708 | },
709 | "scope": 1525,
710 | "src": "347:165:2",
711 | "stateMutability": "nonpayable",
712 | "superFunction": null,
713 | "visibility": "public"
714 | }
715 | ],
716 | "scope": 1526,
717 | "src": "34:480:2"
718 | }
719 | ],
720 | "src": "0:515:2"
721 | },
722 | "legacyAST": {
723 | "absolutePath": "/Users/gregory/code/nft/src/contracts/Migrations.sol",
724 | "exportedSymbols": {
725 | "Migrations": [
726 | 1525
727 | ]
728 | },
729 | "id": 1526,
730 | "nodeType": "SourceUnit",
731 | "nodes": [
732 | {
733 | "id": 1470,
734 | "literals": [
735 | "solidity",
736 | ">=",
737 | "0.4",
738 | ".21",
739 | "<",
740 | "0.6",
741 | ".0"
742 | ],
743 | "nodeType": "PragmaDirective",
744 | "src": "0:32:2"
745 | },
746 | {
747 | "baseContracts": [],
748 | "contractDependencies": [],
749 | "contractKind": "contract",
750 | "documentation": null,
751 | "fullyImplemented": true,
752 | "id": 1525,
753 | "linearizedBaseContracts": [
754 | 1525
755 | ],
756 | "name": "Migrations",
757 | "nodeType": "ContractDefinition",
758 | "nodes": [
759 | {
760 | "constant": false,
761 | "id": 1472,
762 | "name": "owner",
763 | "nodeType": "VariableDeclaration",
764 | "scope": 1525,
765 | "src": "58:20:2",
766 | "stateVariable": true,
767 | "storageLocation": "default",
768 | "typeDescriptions": {
769 | "typeIdentifier": "t_address",
770 | "typeString": "address"
771 | },
772 | "typeName": {
773 | "id": 1471,
774 | "name": "address",
775 | "nodeType": "ElementaryTypeName",
776 | "src": "58:7:2",
777 | "stateMutability": "nonpayable",
778 | "typeDescriptions": {
779 | "typeIdentifier": "t_address",
780 | "typeString": "address"
781 | }
782 | },
783 | "value": null,
784 | "visibility": "public"
785 | },
786 | {
787 | "constant": false,
788 | "id": 1474,
789 | "name": "last_completed_migration",
790 | "nodeType": "VariableDeclaration",
791 | "scope": 1525,
792 | "src": "82:36:2",
793 | "stateVariable": true,
794 | "storageLocation": "default",
795 | "typeDescriptions": {
796 | "typeIdentifier": "t_uint256",
797 | "typeString": "uint256"
798 | },
799 | "typeName": {
800 | "id": 1473,
801 | "name": "uint",
802 | "nodeType": "ElementaryTypeName",
803 | "src": "82:4:2",
804 | "typeDescriptions": {
805 | "typeIdentifier": "t_uint256",
806 | "typeString": "uint256"
807 | }
808 | },
809 | "value": null,
810 | "visibility": "public"
811 | },
812 | {
813 | "body": {
814 | "id": 1482,
815 | "nodeType": "Block",
816 | "src": "144:29:2",
817 | "statements": [
818 | {
819 | "expression": {
820 | "argumentTypes": null,
821 | "id": 1480,
822 | "isConstant": false,
823 | "isLValue": false,
824 | "isPure": false,
825 | "lValueRequested": false,
826 | "leftHandSide": {
827 | "argumentTypes": null,
828 | "id": 1477,
829 | "name": "owner",
830 | "nodeType": "Identifier",
831 | "overloadedDeclarations": [],
832 | "referencedDeclaration": 1472,
833 | "src": "150:5:2",
834 | "typeDescriptions": {
835 | "typeIdentifier": "t_address",
836 | "typeString": "address"
837 | }
838 | },
839 | "nodeType": "Assignment",
840 | "operator": "=",
841 | "rightHandSide": {
842 | "argumentTypes": null,
843 | "expression": {
844 | "argumentTypes": null,
845 | "id": 1478,
846 | "name": "msg",
847 | "nodeType": "Identifier",
848 | "overloadedDeclarations": [],
849 | "referencedDeclaration": 1540,
850 | "src": "158:3:2",
851 | "typeDescriptions": {
852 | "typeIdentifier": "t_magic_message",
853 | "typeString": "msg"
854 | }
855 | },
856 | "id": 1479,
857 | "isConstant": false,
858 | "isLValue": false,
859 | "isPure": false,
860 | "lValueRequested": false,
861 | "memberName": "sender",
862 | "nodeType": "MemberAccess",
863 | "referencedDeclaration": null,
864 | "src": "158:10:2",
865 | "typeDescriptions": {
866 | "typeIdentifier": "t_address_payable",
867 | "typeString": "address payable"
868 | }
869 | },
870 | "src": "150:18:2",
871 | "typeDescriptions": {
872 | "typeIdentifier": "t_address",
873 | "typeString": "address"
874 | }
875 | },
876 | "id": 1481,
877 | "nodeType": "ExpressionStatement",
878 | "src": "150:18:2"
879 | }
880 | ]
881 | },
882 | "documentation": null,
883 | "id": 1483,
884 | "implemented": true,
885 | "kind": "constructor",
886 | "modifiers": [],
887 | "name": "",
888 | "nodeType": "FunctionDefinition",
889 | "parameters": {
890 | "id": 1475,
891 | "nodeType": "ParameterList",
892 | "parameters": [],
893 | "src": "134:2:2"
894 | },
895 | "returnParameters": {
896 | "id": 1476,
897 | "nodeType": "ParameterList",
898 | "parameters": [],
899 | "src": "144:0:2"
900 | },
901 | "scope": 1525,
902 | "src": "123:50:2",
903 | "stateMutability": "nonpayable",
904 | "superFunction": null,
905 | "visibility": "public"
906 | },
907 | {
908 | "body": {
909 | "id": 1491,
910 | "nodeType": "Block",
911 | "src": "199:37:2",
912 | "statements": [
913 | {
914 | "condition": {
915 | "argumentTypes": null,
916 | "commonType": {
917 | "typeIdentifier": "t_address",
918 | "typeString": "address"
919 | },
920 | "id": 1488,
921 | "isConstant": false,
922 | "isLValue": false,
923 | "isPure": false,
924 | "lValueRequested": false,
925 | "leftExpression": {
926 | "argumentTypes": null,
927 | "expression": {
928 | "argumentTypes": null,
929 | "id": 1485,
930 | "name": "msg",
931 | "nodeType": "Identifier",
932 | "overloadedDeclarations": [],
933 | "referencedDeclaration": 1540,
934 | "src": "209:3:2",
935 | "typeDescriptions": {
936 | "typeIdentifier": "t_magic_message",
937 | "typeString": "msg"
938 | }
939 | },
940 | "id": 1486,
941 | "isConstant": false,
942 | "isLValue": false,
943 | "isPure": false,
944 | "lValueRequested": false,
945 | "memberName": "sender",
946 | "nodeType": "MemberAccess",
947 | "referencedDeclaration": null,
948 | "src": "209:10:2",
949 | "typeDescriptions": {
950 | "typeIdentifier": "t_address_payable",
951 | "typeString": "address payable"
952 | }
953 | },
954 | "nodeType": "BinaryOperation",
955 | "operator": "==",
956 | "rightExpression": {
957 | "argumentTypes": null,
958 | "id": 1487,
959 | "name": "owner",
960 | "nodeType": "Identifier",
961 | "overloadedDeclarations": [],
962 | "referencedDeclaration": 1472,
963 | "src": "223:5:2",
964 | "typeDescriptions": {
965 | "typeIdentifier": "t_address",
966 | "typeString": "address"
967 | }
968 | },
969 | "src": "209:19:2",
970 | "typeDescriptions": {
971 | "typeIdentifier": "t_bool",
972 | "typeString": "bool"
973 | }
974 | },
975 | "falseBody": null,
976 | "id": 1490,
977 | "nodeType": "IfStatement",
978 | "src": "205:26:2",
979 | "trueBody": {
980 | "id": 1489,
981 | "nodeType": "PlaceholderStatement",
982 | "src": "230:1:2"
983 | }
984 | }
985 | ]
986 | },
987 | "documentation": null,
988 | "id": 1492,
989 | "name": "restricted",
990 | "nodeType": "ModifierDefinition",
991 | "parameters": {
992 | "id": 1484,
993 | "nodeType": "ParameterList",
994 | "parameters": [],
995 | "src": "196:2:2"
996 | },
997 | "src": "177:59:2",
998 | "visibility": "internal"
999 | },
1000 | {
1001 | "body": {
1002 | "id": 1503,
1003 | "nodeType": "Block",
1004 | "src": "296:47:2",
1005 | "statements": [
1006 | {
1007 | "expression": {
1008 | "argumentTypes": null,
1009 | "id": 1501,
1010 | "isConstant": false,
1011 | "isLValue": false,
1012 | "isPure": false,
1013 | "lValueRequested": false,
1014 | "leftHandSide": {
1015 | "argumentTypes": null,
1016 | "id": 1499,
1017 | "name": "last_completed_migration",
1018 | "nodeType": "Identifier",
1019 | "overloadedDeclarations": [],
1020 | "referencedDeclaration": 1474,
1021 | "src": "302:24:2",
1022 | "typeDescriptions": {
1023 | "typeIdentifier": "t_uint256",
1024 | "typeString": "uint256"
1025 | }
1026 | },
1027 | "nodeType": "Assignment",
1028 | "operator": "=",
1029 | "rightHandSide": {
1030 | "argumentTypes": null,
1031 | "id": 1500,
1032 | "name": "completed",
1033 | "nodeType": "Identifier",
1034 | "overloadedDeclarations": [],
1035 | "referencedDeclaration": 1494,
1036 | "src": "329:9:2",
1037 | "typeDescriptions": {
1038 | "typeIdentifier": "t_uint256",
1039 | "typeString": "uint256"
1040 | }
1041 | },
1042 | "src": "302:36:2",
1043 | "typeDescriptions": {
1044 | "typeIdentifier": "t_uint256",
1045 | "typeString": "uint256"
1046 | }
1047 | },
1048 | "id": 1502,
1049 | "nodeType": "ExpressionStatement",
1050 | "src": "302:36:2"
1051 | }
1052 | ]
1053 | },
1054 | "documentation": null,
1055 | "id": 1504,
1056 | "implemented": true,
1057 | "kind": "function",
1058 | "modifiers": [
1059 | {
1060 | "arguments": null,
1061 | "id": 1497,
1062 | "modifierName": {
1063 | "argumentTypes": null,
1064 | "id": 1496,
1065 | "name": "restricted",
1066 | "nodeType": "Identifier",
1067 | "overloadedDeclarations": [],
1068 | "referencedDeclaration": 1492,
1069 | "src": "285:10:2",
1070 | "typeDescriptions": {
1071 | "typeIdentifier": "t_modifier$__$",
1072 | "typeString": "modifier ()"
1073 | }
1074 | },
1075 | "nodeType": "ModifierInvocation",
1076 | "src": "285:10:2"
1077 | }
1078 | ],
1079 | "name": "setCompleted",
1080 | "nodeType": "FunctionDefinition",
1081 | "parameters": {
1082 | "id": 1495,
1083 | "nodeType": "ParameterList",
1084 | "parameters": [
1085 | {
1086 | "constant": false,
1087 | "id": 1494,
1088 | "name": "completed",
1089 | "nodeType": "VariableDeclaration",
1090 | "scope": 1504,
1091 | "src": "262:14:2",
1092 | "stateVariable": false,
1093 | "storageLocation": "default",
1094 | "typeDescriptions": {
1095 | "typeIdentifier": "t_uint256",
1096 | "typeString": "uint256"
1097 | },
1098 | "typeName": {
1099 | "id": 1493,
1100 | "name": "uint",
1101 | "nodeType": "ElementaryTypeName",
1102 | "src": "262:4:2",
1103 | "typeDescriptions": {
1104 | "typeIdentifier": "t_uint256",
1105 | "typeString": "uint256"
1106 | }
1107 | },
1108 | "value": null,
1109 | "visibility": "internal"
1110 | }
1111 | ],
1112 | "src": "261:16:2"
1113 | },
1114 | "returnParameters": {
1115 | "id": 1498,
1116 | "nodeType": "ParameterList",
1117 | "parameters": [],
1118 | "src": "296:0:2"
1119 | },
1120 | "scope": 1525,
1121 | "src": "240:103:2",
1122 | "stateMutability": "nonpayable",
1123 | "superFunction": null,
1124 | "visibility": "public"
1125 | },
1126 | {
1127 | "body": {
1128 | "id": 1523,
1129 | "nodeType": "Block",
1130 | "src": "403:109:2",
1131 | "statements": [
1132 | {
1133 | "assignments": [
1134 | 1512
1135 | ],
1136 | "declarations": [
1137 | {
1138 | "constant": false,
1139 | "id": 1512,
1140 | "name": "upgraded",
1141 | "nodeType": "VariableDeclaration",
1142 | "scope": 1523,
1143 | "src": "409:19:2",
1144 | "stateVariable": false,
1145 | "storageLocation": "default",
1146 | "typeDescriptions": {
1147 | "typeIdentifier": "t_contract$_Migrations_$1525",
1148 | "typeString": "contract Migrations"
1149 | },
1150 | "typeName": {
1151 | "contractScope": null,
1152 | "id": 1511,
1153 | "name": "Migrations",
1154 | "nodeType": "UserDefinedTypeName",
1155 | "referencedDeclaration": 1525,
1156 | "src": "409:10:2",
1157 | "typeDescriptions": {
1158 | "typeIdentifier": "t_contract$_Migrations_$1525",
1159 | "typeString": "contract Migrations"
1160 | }
1161 | },
1162 | "value": null,
1163 | "visibility": "internal"
1164 | }
1165 | ],
1166 | "id": 1516,
1167 | "initialValue": {
1168 | "argumentTypes": null,
1169 | "arguments": [
1170 | {
1171 | "argumentTypes": null,
1172 | "id": 1514,
1173 | "name": "new_address",
1174 | "nodeType": "Identifier",
1175 | "overloadedDeclarations": [],
1176 | "referencedDeclaration": 1506,
1177 | "src": "442:11:2",
1178 | "typeDescriptions": {
1179 | "typeIdentifier": "t_address",
1180 | "typeString": "address"
1181 | }
1182 | }
1183 | ],
1184 | "expression": {
1185 | "argumentTypes": [
1186 | {
1187 | "typeIdentifier": "t_address",
1188 | "typeString": "address"
1189 | }
1190 | ],
1191 | "id": 1513,
1192 | "name": "Migrations",
1193 | "nodeType": "Identifier",
1194 | "overloadedDeclarations": [],
1195 | "referencedDeclaration": 1525,
1196 | "src": "431:10:2",
1197 | "typeDescriptions": {
1198 | "typeIdentifier": "t_type$_t_contract$_Migrations_$1525_$",
1199 | "typeString": "type(contract Migrations)"
1200 | }
1201 | },
1202 | "id": 1515,
1203 | "isConstant": false,
1204 | "isLValue": false,
1205 | "isPure": false,
1206 | "kind": "typeConversion",
1207 | "lValueRequested": false,
1208 | "names": [],
1209 | "nodeType": "FunctionCall",
1210 | "src": "431:23:2",
1211 | "typeDescriptions": {
1212 | "typeIdentifier": "t_contract$_Migrations_$1525",
1213 | "typeString": "contract Migrations"
1214 | }
1215 | },
1216 | "nodeType": "VariableDeclarationStatement",
1217 | "src": "409:45:2"
1218 | },
1219 | {
1220 | "expression": {
1221 | "argumentTypes": null,
1222 | "arguments": [
1223 | {
1224 | "argumentTypes": null,
1225 | "id": 1520,
1226 | "name": "last_completed_migration",
1227 | "nodeType": "Identifier",
1228 | "overloadedDeclarations": [],
1229 | "referencedDeclaration": 1474,
1230 | "src": "482:24:2",
1231 | "typeDescriptions": {
1232 | "typeIdentifier": "t_uint256",
1233 | "typeString": "uint256"
1234 | }
1235 | }
1236 | ],
1237 | "expression": {
1238 | "argumentTypes": [
1239 | {
1240 | "typeIdentifier": "t_uint256",
1241 | "typeString": "uint256"
1242 | }
1243 | ],
1244 | "expression": {
1245 | "argumentTypes": null,
1246 | "id": 1517,
1247 | "name": "upgraded",
1248 | "nodeType": "Identifier",
1249 | "overloadedDeclarations": [],
1250 | "referencedDeclaration": 1512,
1251 | "src": "460:8:2",
1252 | "typeDescriptions": {
1253 | "typeIdentifier": "t_contract$_Migrations_$1525",
1254 | "typeString": "contract Migrations"
1255 | }
1256 | },
1257 | "id": 1519,
1258 | "isConstant": false,
1259 | "isLValue": false,
1260 | "isPure": false,
1261 | "lValueRequested": false,
1262 | "memberName": "setCompleted",
1263 | "nodeType": "MemberAccess",
1264 | "referencedDeclaration": 1504,
1265 | "src": "460:21:2",
1266 | "typeDescriptions": {
1267 | "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$",
1268 | "typeString": "function (uint256) external"
1269 | }
1270 | },
1271 | "id": 1521,
1272 | "isConstant": false,
1273 | "isLValue": false,
1274 | "isPure": false,
1275 | "kind": "functionCall",
1276 | "lValueRequested": false,
1277 | "names": [],
1278 | "nodeType": "FunctionCall",
1279 | "src": "460:47:2",
1280 | "typeDescriptions": {
1281 | "typeIdentifier": "t_tuple$__$",
1282 | "typeString": "tuple()"
1283 | }
1284 | },
1285 | "id": 1522,
1286 | "nodeType": "ExpressionStatement",
1287 | "src": "460:47:2"
1288 | }
1289 | ]
1290 | },
1291 | "documentation": null,
1292 | "id": 1524,
1293 | "implemented": true,
1294 | "kind": "function",
1295 | "modifiers": [
1296 | {
1297 | "arguments": null,
1298 | "id": 1509,
1299 | "modifierName": {
1300 | "argumentTypes": null,
1301 | "id": 1508,
1302 | "name": "restricted",
1303 | "nodeType": "Identifier",
1304 | "overloadedDeclarations": [],
1305 | "referencedDeclaration": 1492,
1306 | "src": "392:10:2",
1307 | "typeDescriptions": {
1308 | "typeIdentifier": "t_modifier$__$",
1309 | "typeString": "modifier ()"
1310 | }
1311 | },
1312 | "nodeType": "ModifierInvocation",
1313 | "src": "392:10:2"
1314 | }
1315 | ],
1316 | "name": "upgrade",
1317 | "nodeType": "FunctionDefinition",
1318 | "parameters": {
1319 | "id": 1507,
1320 | "nodeType": "ParameterList",
1321 | "parameters": [
1322 | {
1323 | "constant": false,
1324 | "id": 1506,
1325 | "name": "new_address",
1326 | "nodeType": "VariableDeclaration",
1327 | "scope": 1524,
1328 | "src": "364:19:2",
1329 | "stateVariable": false,
1330 | "storageLocation": "default",
1331 | "typeDescriptions": {
1332 | "typeIdentifier": "t_address",
1333 | "typeString": "address"
1334 | },
1335 | "typeName": {
1336 | "id": 1505,
1337 | "name": "address",
1338 | "nodeType": "ElementaryTypeName",
1339 | "src": "364:7:2",
1340 | "stateMutability": "nonpayable",
1341 | "typeDescriptions": {
1342 | "typeIdentifier": "t_address",
1343 | "typeString": "address"
1344 | }
1345 | },
1346 | "value": null,
1347 | "visibility": "internal"
1348 | }
1349 | ],
1350 | "src": "363:21:2"
1351 | },
1352 | "returnParameters": {
1353 | "id": 1510,
1354 | "nodeType": "ParameterList",
1355 | "parameters": [],
1356 | "src": "403:0:2"
1357 | },
1358 | "scope": 1525,
1359 | "src": "347:165:2",
1360 | "stateMutability": "nonpayable",
1361 | "superFunction": null,
1362 | "visibility": "public"
1363 | }
1364 | ],
1365 | "scope": 1526,
1366 | "src": "34:480:2"
1367 | }
1368 | ],
1369 | "src": "0:515:2"
1370 | },
1371 | "compiler": {
1372 | "name": "solc",
1373 | "version": "0.5.0+commit.1d4f565a.Emscripten.clang"
1374 | },
1375 | "networks": {},
1376 | "schemaVersion": "3.0.2",
1377 | "updatedAt": "2019-09-05T15:46:34.745Z",
1378 | "devdoc": {
1379 | "methods": {}
1380 | },
1381 | "userdoc": {
1382 | "methods": {}
1383 | }
1384 | }
--------------------------------------------------------------------------------