├── .babelrc
├── .env_example
├── .gitignore
├── README.md
├── migrations
├── 1_initial_migration.js
└── 2_deploy_contracts.js
├── package-lock.json
├── package.json
├── public
├── cryptologo.png
├── favicon.png
├── images
│ └── Screenshot (24).png
├── index.html
└── manifest.json
├── src
├── abis
│ ├── Decentragram.json
│ └── Migrations.json
├── components
│ ├── App.css
│ ├── App.js
│ ├── Main.js
│ └── Navbar.js
├── contract
│ └── Crytogram.sol
├── cryptologo.png
├── index.js
├── logo.png
├── photo.png
└── serviceWorker.js
├── test
└── test.js
└── truffle-config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2", "stage-3"]
3 | }
4 |
--------------------------------------------------------------------------------
/.env_example:
--------------------------------------------------------------------------------
1 | PRIVATE_KEYS='bc81d50cb672e32ff42476b56a4e254258a29f32af7db3d148bd6141862cf147'
2 | INFURA_API_KEY=
3 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Decentralized Social Media web app using Ethereum Blockchain.
2 |
3 | ## Team Details
4 | Team Name : TECH MINDS
id: 72a0c21c36
5 |
6 | ## Project Description
7 | A completely decentralized social media website that enables users to interact with their friends and relatives without compromising their privacy and personal info. It has all the functionalities of a traditional social media app like user profiles, friends, feed, posts, chat, etc. All the data including image files will be stored in a secure decentralized network(IPFS) and no entity ( government or private) has any control over it, thus giving the users total assurance of their privacy.
8 | But due to lack of time we were only able to do upto the stage where we can add photos in ethereum blockchain with a user defined description.
9 | And insted we also added a feature where other users can tip some amount of Ethers for a given post.
10 |
11 | ## Team Members:
12 |
13 | 1. [Achyuth Mohan](https://github.com/AchyuthMohan)
14 | 2. [Adithya Ajith](https://github.com/XdithyX)
15 | 3. [Jagannath E Shahi](https://github.com/Jagannathes)
16 | 4. [Jaison Dennis](https://github.com/jaison080)
17 |
18 | ## 🔧 Project UI:
19 | .png)
20 | # Steps To run the project:
21 | ```bash
22 | git clone https://github.com/AchyuthMohan/Blockchain-decentragram
23 | cd Blockchain-decentragram
24 | git checkout master
25 | npm install
26 | npm start
27 | ```
28 | ## Contracts Deployment settings:
29 | 1. Create an account in remix.com.
30 | 2. Create new project and inside contracts folder add a new solidity file named contracts.sol.
31 | 3. Inside contracts file paste the contracts.sol file contents from our projects.
32 | 4. Make the settings into web 3 mode and compile.
33 | 5. Next connect the local metamask account with remix in Rinkeby Ethereum mode.
34 | 6. Deploy the project and paste the generated address into our networks section in package-lock.json file.
35 |
36 | ## Technologies used:
37 | React js for Front-End, Web3 js, npm truffle, solidity for contracts scripting and Ethereum blockchain.
38 |
--------------------------------------------------------------------------------
/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | const Migrations = artifacts.require("Migrations");
2 |
3 | module.exports = function(deployer) {
4 | deployer.deploy(Migrations);
5 | };
6 |
--------------------------------------------------------------------------------
/migrations/2_deploy_contracts.js:
--------------------------------------------------------------------------------
1 | const Decentragram = artifacts.require("Decentragram");
2 |
3 | module.exports = function(deployer) {
4 | deployer.deploy(Decentragram);
5 | };
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Cryptogram",
3 | "version": "0.1.0",
4 | "description": "Decentralized Social Media",
5 | "author": "Tech Minds",
6 | "homepage": ".",
7 | "dependencies": {
8 | "@truffle/hdwallet-provider": "^1.1.0",
9 | "babel-polyfill": "6.26.0",
10 | "babel-preset-env": "1.7.0",
11 | "babel-preset-es2015": "6.24.1",
12 | "babel-preset-stage-2": "6.24.1",
13 | "babel-preset-stage-3": "6.24.1",
14 | "babel-register": "6.26.0",
15 | "bootstrap": "^4.5.2",
16 | "chai": "4.2.0",
17 | "chai-as-promised": "7.1.1",
18 | "chai-bignumber": "3.0.0",
19 | "dotenv": "^8.2.0",
20 | "identicon.js": "^2.3.3",
21 | "ipfs-http-client": "^33.1.1",
22 | "react": "^16.13.1",
23 | "react-bootstrap": "^1.3.0",
24 | "react-dom": "^16.13.1",
25 | "react-scripts": "^3.4.3",
26 | "truffle": "^5.4.30",
27 | "truffle-hdwallet-provider-privkey": "^0.3.0",
28 | "web3": "^1.3.0"
29 | },
30 | "scripts": {
31 | "start": "react-scripts start",
32 | "build": "react-scripts build",
33 | "test": "react-scripts test",
34 | "eject": "react-scripts eject",
35 | "predeploy": "npm run build",
36 | "deploy": "gh-pages -d build"
37 | },
38 | "eslintConfig": {
39 | "extends": "react-app"
40 | },
41 | "browserslist": [
42 | ">0.2%",
43 | "not dead",
44 | "not ie <= 11",
45 | "not op_mini all"
46 | ],
47 | "devDependencies": {
48 | "gh-pages": "^2.2.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/public/cryptologo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AchyuthMohan/Blockchain-Cryptogram/1131b4421f5db99f3a21a63894f0e7e3793a0820/public/cryptologo.png
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AchyuthMohan/Blockchain-Cryptogram/1131b4421f5db99f3a21a63894f0e7e3793a0820/public/favicon.png
--------------------------------------------------------------------------------
/public/images/Screenshot (24).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AchyuthMohan/Blockchain-Cryptogram/1131b4421f5db99f3a21a63894f0e7e3793a0820/public/images/Screenshot (24).png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
15 |
16 |
25 | Cryptogram
26 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/abis/Migrations.json:
--------------------------------------------------------------------------------
1 | {
2 | "contractName": "Migrations",
3 | "abi": [
4 | {
5 | "inputs": [],
6 | "payable": false,
7 | "stateMutability": "nonpayable",
8 | "type": "constructor"
9 | },
10 | {
11 | "constant": true,
12 | "inputs": [],
13 | "name": "last_completed_migration",
14 | "outputs": [
15 | {
16 | "internalType": "uint256",
17 | "name": "",
18 | "type": "uint256"
19 | }
20 | ],
21 | "payable": false,
22 | "stateMutability": "view",
23 | "type": "function"
24 | },
25 | {
26 | "constant": true,
27 | "inputs": [],
28 | "name": "owner",
29 | "outputs": [
30 | {
31 | "internalType": "address",
32 | "name": "",
33 | "type": "address"
34 | }
35 | ],
36 | "payable": false,
37 | "stateMutability": "view",
38 | "type": "function"
39 | },
40 | {
41 | "constant": false,
42 | "inputs": [
43 | {
44 | "internalType": "uint256",
45 | "name": "completed",
46 | "type": "uint256"
47 | }
48 | ],
49 | "name": "setCompleted",
50 | "outputs": [],
51 | "payable": false,
52 | "stateMutability": "nonpayable",
53 | "type": "function"
54 | },
55 | {
56 | "constant": false,
57 | "inputs": [
58 | {
59 | "internalType": "address",
60 | "name": "new_address",
61 | "type": "address"
62 | }
63 | ],
64 | "name": "upgrade",
65 | "outputs": [],
66 | "payable": false,
67 | "stateMutability": "nonpayable",
68 | "type": "function"
69 | }
70 | ],
71 | "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":true,\"inputs\":[],\"name\":\"last_completed_migration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"completed\",\"type\":\"uint256\"}],\"name\":\"setCompleted\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"new_address\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"/mnt/c/pr0/decentragram/src/contracts/Migrations.sol\":\"Migrations\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"/mnt/c/pr0/decentragram/src/contracts/Migrations.sol\":{\"keccak256\":\"0xfdb731592344e2a2890faf03baec7b4bee7057ffba18ba6dbb6eec8db85f8f4c\",\"urls\":[\"bzz-raw://f9b488bbb84816dd04c1b155e943319758db16ee943943648fb264bccecc9879\",\"dweb:/ipfs/QmbW34mYrj3uLteyHf3S46pnp9bnwovtCXHbdBHfzMkSZx\"]}},\"version\":1}",
72 | "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102b7806100606000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80630900f01014610051578063445df0ac146100955780638da5cb5b146100b3578063fdacd576146100fd575b600080fd5b6100936004803603602081101561006757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061012b565b005b61009d6101f7565b6040518082815260200191505060405180910390f35b6100bb6101fd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101296004803603602081101561011357600080fd5b8101908080359060200190929190505050610222565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101f45760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156101da57600080fd5b505af11580156101ee573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561027f57806001819055505b5056fea265627a7a723158202f587e55e41a33b8872f3e1f3f2a9389bba4c619d765885d7aa12281bc7e618864736f6c63430005100032",
73 | "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630900f01014610051578063445df0ac146100955780638da5cb5b146100b3578063fdacd576146100fd575b600080fd5b6100936004803603602081101561006757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061012b565b005b61009d6101f7565b6040518082815260200191505060405180910390f35b6100bb6101fd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101296004803603602081101561011357600080fd5b8101908080359060200190929190505050610222565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101f45760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156101da57600080fd5b505af11580156101ee573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561027f57806001819055505b5056fea265627a7a723158202f587e55e41a33b8872f3e1f3f2a9389bba4c619d765885d7aa12281bc7e618864736f6c63430005100032",
74 | "sourceMap": "34:480:3:-;;;123:50;8:9:-1;5:2;;;30:1;27;20:12;5:2;123:50:3;158:10;150:5;;:18;;;;;;;;;;;;;;;;;;34:480;;;;;;",
75 | "deployedSourceMap": "34:480:3:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34:480:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;347:165:3;;;;;;;;;;;;;;;;;;;:::i;:::-;;82:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;58:20;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;240:103;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;240:103:3;;;;;;;;;;;;;;;;;:::i;:::-;;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:3;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;460:47:3;;;;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",
76 | "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",
77 | "sourcePath": "/mnt/c/pr0/decentragram/src/contracts/Migrations.sol",
78 | "ast": {
79 | "absolutePath": "/mnt/c/pr0/decentragram/src/contracts/Migrations.sol",
80 | "exportedSymbols": {
81 | "Migrations": [
82 | 467
83 | ]
84 | },
85 | "id": 468,
86 | "nodeType": "SourceUnit",
87 | "nodes": [
88 | {
89 | "id": 412,
90 | "literals": [
91 | "solidity",
92 | ">=",
93 | "0.4",
94 | ".21",
95 | "<",
96 | "0.6",
97 | ".0"
98 | ],
99 | "nodeType": "PragmaDirective",
100 | "src": "0:32:3"
101 | },
102 | {
103 | "baseContracts": [],
104 | "contractDependencies": [],
105 | "contractKind": "contract",
106 | "documentation": null,
107 | "fullyImplemented": true,
108 | "id": 467,
109 | "linearizedBaseContracts": [
110 | 467
111 | ],
112 | "name": "Migrations",
113 | "nodeType": "ContractDefinition",
114 | "nodes": [
115 | {
116 | "constant": false,
117 | "id": 414,
118 | "name": "owner",
119 | "nodeType": "VariableDeclaration",
120 | "scope": 467,
121 | "src": "58:20:3",
122 | "stateVariable": true,
123 | "storageLocation": "default",
124 | "typeDescriptions": {
125 | "typeIdentifier": "t_address",
126 | "typeString": "address"
127 | },
128 | "typeName": {
129 | "id": 413,
130 | "name": "address",
131 | "nodeType": "ElementaryTypeName",
132 | "src": "58:7:3",
133 | "stateMutability": "nonpayable",
134 | "typeDescriptions": {
135 | "typeIdentifier": "t_address",
136 | "typeString": "address"
137 | }
138 | },
139 | "value": null,
140 | "visibility": "public"
141 | },
142 | {
143 | "constant": false,
144 | "id": 416,
145 | "name": "last_completed_migration",
146 | "nodeType": "VariableDeclaration",
147 | "scope": 467,
148 | "src": "82:36:3",
149 | "stateVariable": true,
150 | "storageLocation": "default",
151 | "typeDescriptions": {
152 | "typeIdentifier": "t_uint256",
153 | "typeString": "uint256"
154 | },
155 | "typeName": {
156 | "id": 415,
157 | "name": "uint",
158 | "nodeType": "ElementaryTypeName",
159 | "src": "82:4:3",
160 | "typeDescriptions": {
161 | "typeIdentifier": "t_uint256",
162 | "typeString": "uint256"
163 | }
164 | },
165 | "value": null,
166 | "visibility": "public"
167 | },
168 | {
169 | "body": {
170 | "id": 424,
171 | "nodeType": "Block",
172 | "src": "144:29:3",
173 | "statements": [
174 | {
175 | "expression": {
176 | "argumentTypes": null,
177 | "id": 422,
178 | "isConstant": false,
179 | "isLValue": false,
180 | "isPure": false,
181 | "lValueRequested": false,
182 | "leftHandSide": {
183 | "argumentTypes": null,
184 | "id": 419,
185 | "name": "owner",
186 | "nodeType": "Identifier",
187 | "overloadedDeclarations": [],
188 | "referencedDeclaration": 414,
189 | "src": "150:5:3",
190 | "typeDescriptions": {
191 | "typeIdentifier": "t_address",
192 | "typeString": "address"
193 | }
194 | },
195 | "nodeType": "Assignment",
196 | "operator": "=",
197 | "rightHandSide": {
198 | "argumentTypes": null,
199 | "expression": {
200 | "argumentTypes": null,
201 | "id": 420,
202 | "name": "msg",
203 | "nodeType": "Identifier",
204 | "overloadedDeclarations": [],
205 | "referencedDeclaration": 482,
206 | "src": "158:3:3",
207 | "typeDescriptions": {
208 | "typeIdentifier": "t_magic_message",
209 | "typeString": "msg"
210 | }
211 | },
212 | "id": 421,
213 | "isConstant": false,
214 | "isLValue": false,
215 | "isPure": false,
216 | "lValueRequested": false,
217 | "memberName": "sender",
218 | "nodeType": "MemberAccess",
219 | "referencedDeclaration": null,
220 | "src": "158:10:3",
221 | "typeDescriptions": {
222 | "typeIdentifier": "t_address_payable",
223 | "typeString": "address payable"
224 | }
225 | },
226 | "src": "150:18:3",
227 | "typeDescriptions": {
228 | "typeIdentifier": "t_address",
229 | "typeString": "address"
230 | }
231 | },
232 | "id": 423,
233 | "nodeType": "ExpressionStatement",
234 | "src": "150:18:3"
235 | }
236 | ]
237 | },
238 | "documentation": null,
239 | "id": 425,
240 | "implemented": true,
241 | "kind": "constructor",
242 | "modifiers": [],
243 | "name": "",
244 | "nodeType": "FunctionDefinition",
245 | "parameters": {
246 | "id": 417,
247 | "nodeType": "ParameterList",
248 | "parameters": [],
249 | "src": "134:2:3"
250 | },
251 | "returnParameters": {
252 | "id": 418,
253 | "nodeType": "ParameterList",
254 | "parameters": [],
255 | "src": "144:0:3"
256 | },
257 | "scope": 467,
258 | "src": "123:50:3",
259 | "stateMutability": "nonpayable",
260 | "superFunction": null,
261 | "visibility": "public"
262 | },
263 | {
264 | "body": {
265 | "id": 433,
266 | "nodeType": "Block",
267 | "src": "199:37:3",
268 | "statements": [
269 | {
270 | "condition": {
271 | "argumentTypes": null,
272 | "commonType": {
273 | "typeIdentifier": "t_address",
274 | "typeString": "address"
275 | },
276 | "id": 430,
277 | "isConstant": false,
278 | "isLValue": false,
279 | "isPure": false,
280 | "lValueRequested": false,
281 | "leftExpression": {
282 | "argumentTypes": null,
283 | "expression": {
284 | "argumentTypes": null,
285 | "id": 427,
286 | "name": "msg",
287 | "nodeType": "Identifier",
288 | "overloadedDeclarations": [],
289 | "referencedDeclaration": 482,
290 | "src": "209:3:3",
291 | "typeDescriptions": {
292 | "typeIdentifier": "t_magic_message",
293 | "typeString": "msg"
294 | }
295 | },
296 | "id": 428,
297 | "isConstant": false,
298 | "isLValue": false,
299 | "isPure": false,
300 | "lValueRequested": false,
301 | "memberName": "sender",
302 | "nodeType": "MemberAccess",
303 | "referencedDeclaration": null,
304 | "src": "209:10:3",
305 | "typeDescriptions": {
306 | "typeIdentifier": "t_address_payable",
307 | "typeString": "address payable"
308 | }
309 | },
310 | "nodeType": "BinaryOperation",
311 | "operator": "==",
312 | "rightExpression": {
313 | "argumentTypes": null,
314 | "id": 429,
315 | "name": "owner",
316 | "nodeType": "Identifier",
317 | "overloadedDeclarations": [],
318 | "referencedDeclaration": 414,
319 | "src": "223:5:3",
320 | "typeDescriptions": {
321 | "typeIdentifier": "t_address",
322 | "typeString": "address"
323 | }
324 | },
325 | "src": "209:19:3",
326 | "typeDescriptions": {
327 | "typeIdentifier": "t_bool",
328 | "typeString": "bool"
329 | }
330 | },
331 | "falseBody": null,
332 | "id": 432,
333 | "nodeType": "IfStatement",
334 | "src": "205:26:3",
335 | "trueBody": {
336 | "id": 431,
337 | "nodeType": "PlaceholderStatement",
338 | "src": "230:1:3"
339 | }
340 | }
341 | ]
342 | },
343 | "documentation": null,
344 | "id": 434,
345 | "name": "restricted",
346 | "nodeType": "ModifierDefinition",
347 | "parameters": {
348 | "id": 426,
349 | "nodeType": "ParameterList",
350 | "parameters": [],
351 | "src": "196:2:3"
352 | },
353 | "src": "177:59:3",
354 | "visibility": "internal"
355 | },
356 | {
357 | "body": {
358 | "id": 445,
359 | "nodeType": "Block",
360 | "src": "296:47:3",
361 | "statements": [
362 | {
363 | "expression": {
364 | "argumentTypes": null,
365 | "id": 443,
366 | "isConstant": false,
367 | "isLValue": false,
368 | "isPure": false,
369 | "lValueRequested": false,
370 | "leftHandSide": {
371 | "argumentTypes": null,
372 | "id": 441,
373 | "name": "last_completed_migration",
374 | "nodeType": "Identifier",
375 | "overloadedDeclarations": [],
376 | "referencedDeclaration": 416,
377 | "src": "302:24:3",
378 | "typeDescriptions": {
379 | "typeIdentifier": "t_uint256",
380 | "typeString": "uint256"
381 | }
382 | },
383 | "nodeType": "Assignment",
384 | "operator": "=",
385 | "rightHandSide": {
386 | "argumentTypes": null,
387 | "id": 442,
388 | "name": "completed",
389 | "nodeType": "Identifier",
390 | "overloadedDeclarations": [],
391 | "referencedDeclaration": 436,
392 | "src": "329:9:3",
393 | "typeDescriptions": {
394 | "typeIdentifier": "t_uint256",
395 | "typeString": "uint256"
396 | }
397 | },
398 | "src": "302:36:3",
399 | "typeDescriptions": {
400 | "typeIdentifier": "t_uint256",
401 | "typeString": "uint256"
402 | }
403 | },
404 | "id": 444,
405 | "nodeType": "ExpressionStatement",
406 | "src": "302:36:3"
407 | }
408 | ]
409 | },
410 | "documentation": null,
411 | "id": 446,
412 | "implemented": true,
413 | "kind": "function",
414 | "modifiers": [
415 | {
416 | "arguments": null,
417 | "id": 439,
418 | "modifierName": {
419 | "argumentTypes": null,
420 | "id": 438,
421 | "name": "restricted",
422 | "nodeType": "Identifier",
423 | "overloadedDeclarations": [],
424 | "referencedDeclaration": 434,
425 | "src": "285:10:3",
426 | "typeDescriptions": {
427 | "typeIdentifier": "t_modifier$__$",
428 | "typeString": "modifier ()"
429 | }
430 | },
431 | "nodeType": "ModifierInvocation",
432 | "src": "285:10:3"
433 | }
434 | ],
435 | "name": "setCompleted",
436 | "nodeType": "FunctionDefinition",
437 | "parameters": {
438 | "id": 437,
439 | "nodeType": "ParameterList",
440 | "parameters": [
441 | {
442 | "constant": false,
443 | "id": 436,
444 | "name": "completed",
445 | "nodeType": "VariableDeclaration",
446 | "scope": 446,
447 | "src": "262:14:3",
448 | "stateVariable": false,
449 | "storageLocation": "default",
450 | "typeDescriptions": {
451 | "typeIdentifier": "t_uint256",
452 | "typeString": "uint256"
453 | },
454 | "typeName": {
455 | "id": 435,
456 | "name": "uint",
457 | "nodeType": "ElementaryTypeName",
458 | "src": "262:4:3",
459 | "typeDescriptions": {
460 | "typeIdentifier": "t_uint256",
461 | "typeString": "uint256"
462 | }
463 | },
464 | "value": null,
465 | "visibility": "internal"
466 | }
467 | ],
468 | "src": "261:16:3"
469 | },
470 | "returnParameters": {
471 | "id": 440,
472 | "nodeType": "ParameterList",
473 | "parameters": [],
474 | "src": "296:0:3"
475 | },
476 | "scope": 467,
477 | "src": "240:103:3",
478 | "stateMutability": "nonpayable",
479 | "superFunction": null,
480 | "visibility": "public"
481 | },
482 | {
483 | "body": {
484 | "id": 465,
485 | "nodeType": "Block",
486 | "src": "403:109:3",
487 | "statements": [
488 | {
489 | "assignments": [
490 | 454
491 | ],
492 | "declarations": [
493 | {
494 | "constant": false,
495 | "id": 454,
496 | "name": "upgraded",
497 | "nodeType": "VariableDeclaration",
498 | "scope": 465,
499 | "src": "409:19:3",
500 | "stateVariable": false,
501 | "storageLocation": "default",
502 | "typeDescriptions": {
503 | "typeIdentifier": "t_contract$_Migrations_$467",
504 | "typeString": "contract Migrations"
505 | },
506 | "typeName": {
507 | "contractScope": null,
508 | "id": 453,
509 | "name": "Migrations",
510 | "nodeType": "UserDefinedTypeName",
511 | "referencedDeclaration": 467,
512 | "src": "409:10:3",
513 | "typeDescriptions": {
514 | "typeIdentifier": "t_contract$_Migrations_$467",
515 | "typeString": "contract Migrations"
516 | }
517 | },
518 | "value": null,
519 | "visibility": "internal"
520 | }
521 | ],
522 | "id": 458,
523 | "initialValue": {
524 | "argumentTypes": null,
525 | "arguments": [
526 | {
527 | "argumentTypes": null,
528 | "id": 456,
529 | "name": "new_address",
530 | "nodeType": "Identifier",
531 | "overloadedDeclarations": [],
532 | "referencedDeclaration": 448,
533 | "src": "442:11:3",
534 | "typeDescriptions": {
535 | "typeIdentifier": "t_address",
536 | "typeString": "address"
537 | }
538 | }
539 | ],
540 | "expression": {
541 | "argumentTypes": [
542 | {
543 | "typeIdentifier": "t_address",
544 | "typeString": "address"
545 | }
546 | ],
547 | "id": 455,
548 | "name": "Migrations",
549 | "nodeType": "Identifier",
550 | "overloadedDeclarations": [],
551 | "referencedDeclaration": 467,
552 | "src": "431:10:3",
553 | "typeDescriptions": {
554 | "typeIdentifier": "t_type$_t_contract$_Migrations_$467_$",
555 | "typeString": "type(contract Migrations)"
556 | }
557 | },
558 | "id": 457,
559 | "isConstant": false,
560 | "isLValue": false,
561 | "isPure": false,
562 | "kind": "typeConversion",
563 | "lValueRequested": false,
564 | "names": [],
565 | "nodeType": "FunctionCall",
566 | "src": "431:23:3",
567 | "typeDescriptions": {
568 | "typeIdentifier": "t_contract$_Migrations_$467",
569 | "typeString": "contract Migrations"
570 | }
571 | },
572 | "nodeType": "VariableDeclarationStatement",
573 | "src": "409:45:3"
574 | },
575 | {
576 | "expression": {
577 | "argumentTypes": null,
578 | "arguments": [
579 | {
580 | "argumentTypes": null,
581 | "id": 462,
582 | "name": "last_completed_migration",
583 | "nodeType": "Identifier",
584 | "overloadedDeclarations": [],
585 | "referencedDeclaration": 416,
586 | "src": "482:24:3",
587 | "typeDescriptions": {
588 | "typeIdentifier": "t_uint256",
589 | "typeString": "uint256"
590 | }
591 | }
592 | ],
593 | "expression": {
594 | "argumentTypes": [
595 | {
596 | "typeIdentifier": "t_uint256",
597 | "typeString": "uint256"
598 | }
599 | ],
600 | "expression": {
601 | "argumentTypes": null,
602 | "id": 459,
603 | "name": "upgraded",
604 | "nodeType": "Identifier",
605 | "overloadedDeclarations": [],
606 | "referencedDeclaration": 454,
607 | "src": "460:8:3",
608 | "typeDescriptions": {
609 | "typeIdentifier": "t_contract$_Migrations_$467",
610 | "typeString": "contract Migrations"
611 | }
612 | },
613 | "id": 461,
614 | "isConstant": false,
615 | "isLValue": false,
616 | "isPure": false,
617 | "lValueRequested": false,
618 | "memberName": "setCompleted",
619 | "nodeType": "MemberAccess",
620 | "referencedDeclaration": 446,
621 | "src": "460:21:3",
622 | "typeDescriptions": {
623 | "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$",
624 | "typeString": "function (uint256) external"
625 | }
626 | },
627 | "id": 463,
628 | "isConstant": false,
629 | "isLValue": false,
630 | "isPure": false,
631 | "kind": "functionCall",
632 | "lValueRequested": false,
633 | "names": [],
634 | "nodeType": "FunctionCall",
635 | "src": "460:47:3",
636 | "typeDescriptions": {
637 | "typeIdentifier": "t_tuple$__$",
638 | "typeString": "tuple()"
639 | }
640 | },
641 | "id": 464,
642 | "nodeType": "ExpressionStatement",
643 | "src": "460:47:3"
644 | }
645 | ]
646 | },
647 | "documentation": null,
648 | "id": 466,
649 | "implemented": true,
650 | "kind": "function",
651 | "modifiers": [
652 | {
653 | "arguments": null,
654 | "id": 451,
655 | "modifierName": {
656 | "argumentTypes": null,
657 | "id": 450,
658 | "name": "restricted",
659 | "nodeType": "Identifier",
660 | "overloadedDeclarations": [],
661 | "referencedDeclaration": 434,
662 | "src": "392:10:3",
663 | "typeDescriptions": {
664 | "typeIdentifier": "t_modifier$__$",
665 | "typeString": "modifier ()"
666 | }
667 | },
668 | "nodeType": "ModifierInvocation",
669 | "src": "392:10:3"
670 | }
671 | ],
672 | "name": "upgrade",
673 | "nodeType": "FunctionDefinition",
674 | "parameters": {
675 | "id": 449,
676 | "nodeType": "ParameterList",
677 | "parameters": [
678 | {
679 | "constant": false,
680 | "id": 448,
681 | "name": "new_address",
682 | "nodeType": "VariableDeclaration",
683 | "scope": 466,
684 | "src": "364:19:3",
685 | "stateVariable": false,
686 | "storageLocation": "default",
687 | "typeDescriptions": {
688 | "typeIdentifier": "t_address",
689 | "typeString": "address"
690 | },
691 | "typeName": {
692 | "id": 447,
693 | "name": "address",
694 | "nodeType": "ElementaryTypeName",
695 | "src": "364:7:3",
696 | "stateMutability": "nonpayable",
697 | "typeDescriptions": {
698 | "typeIdentifier": "t_address",
699 | "typeString": "address"
700 | }
701 | },
702 | "value": null,
703 | "visibility": "internal"
704 | }
705 | ],
706 | "src": "363:21:3"
707 | },
708 | "returnParameters": {
709 | "id": 452,
710 | "nodeType": "ParameterList",
711 | "parameters": [],
712 | "src": "403:0:3"
713 | },
714 | "scope": 467,
715 | "src": "347:165:3",
716 | "stateMutability": "nonpayable",
717 | "superFunction": null,
718 | "visibility": "public"
719 | }
720 | ],
721 | "scope": 468,
722 | "src": "34:480:3"
723 | }
724 | ],
725 | "src": "0:515:3"
726 | },
727 | "legacyAST": {
728 | "absolutePath": "/mnt/c/pr0/decentragram/src/contracts/Migrations.sol",
729 | "exportedSymbols": {
730 | "Migrations": [
731 | 467
732 | ]
733 | },
734 | "id": 468,
735 | "nodeType": "SourceUnit",
736 | "nodes": [
737 | {
738 | "id": 412,
739 | "literals": [
740 | "solidity",
741 | ">=",
742 | "0.4",
743 | ".21",
744 | "<",
745 | "0.6",
746 | ".0"
747 | ],
748 | "nodeType": "PragmaDirective",
749 | "src": "0:32:3"
750 | },
751 | {
752 | "baseContracts": [],
753 | "contractDependencies": [],
754 | "contractKind": "contract",
755 | "documentation": null,
756 | "fullyImplemented": true,
757 | "id": 467,
758 | "linearizedBaseContracts": [
759 | 467
760 | ],
761 | "name": "Migrations",
762 | "nodeType": "ContractDefinition",
763 | "nodes": [
764 | {
765 | "constant": false,
766 | "id": 414,
767 | "name": "owner",
768 | "nodeType": "VariableDeclaration",
769 | "scope": 467,
770 | "src": "58:20:3",
771 | "stateVariable": true,
772 | "storageLocation": "default",
773 | "typeDescriptions": {
774 | "typeIdentifier": "t_address",
775 | "typeString": "address"
776 | },
777 | "typeName": {
778 | "id": 413,
779 | "name": "address",
780 | "nodeType": "ElementaryTypeName",
781 | "src": "58:7:3",
782 | "stateMutability": "nonpayable",
783 | "typeDescriptions": {
784 | "typeIdentifier": "t_address",
785 | "typeString": "address"
786 | }
787 | },
788 | "value": null,
789 | "visibility": "public"
790 | },
791 | {
792 | "constant": false,
793 | "id": 416,
794 | "name": "last_completed_migration",
795 | "nodeType": "VariableDeclaration",
796 | "scope": 467,
797 | "src": "82:36:3",
798 | "stateVariable": true,
799 | "storageLocation": "default",
800 | "typeDescriptions": {
801 | "typeIdentifier": "t_uint256",
802 | "typeString": "uint256"
803 | },
804 | "typeName": {
805 | "id": 415,
806 | "name": "uint",
807 | "nodeType": "ElementaryTypeName",
808 | "src": "82:4:3",
809 | "typeDescriptions": {
810 | "typeIdentifier": "t_uint256",
811 | "typeString": "uint256"
812 | }
813 | },
814 | "value": null,
815 | "visibility": "public"
816 | },
817 | {
818 | "body": {
819 | "id": 424,
820 | "nodeType": "Block",
821 | "src": "144:29:3",
822 | "statements": [
823 | {
824 | "expression": {
825 | "argumentTypes": null,
826 | "id": 422,
827 | "isConstant": false,
828 | "isLValue": false,
829 | "isPure": false,
830 | "lValueRequested": false,
831 | "leftHandSide": {
832 | "argumentTypes": null,
833 | "id": 419,
834 | "name": "owner",
835 | "nodeType": "Identifier",
836 | "overloadedDeclarations": [],
837 | "referencedDeclaration": 414,
838 | "src": "150:5:3",
839 | "typeDescriptions": {
840 | "typeIdentifier": "t_address",
841 | "typeString": "address"
842 | }
843 | },
844 | "nodeType": "Assignment",
845 | "operator": "=",
846 | "rightHandSide": {
847 | "argumentTypes": null,
848 | "expression": {
849 | "argumentTypes": null,
850 | "id": 420,
851 | "name": "msg",
852 | "nodeType": "Identifier",
853 | "overloadedDeclarations": [],
854 | "referencedDeclaration": 482,
855 | "src": "158:3:3",
856 | "typeDescriptions": {
857 | "typeIdentifier": "t_magic_message",
858 | "typeString": "msg"
859 | }
860 | },
861 | "id": 421,
862 | "isConstant": false,
863 | "isLValue": false,
864 | "isPure": false,
865 | "lValueRequested": false,
866 | "memberName": "sender",
867 | "nodeType": "MemberAccess",
868 | "referencedDeclaration": null,
869 | "src": "158:10:3",
870 | "typeDescriptions": {
871 | "typeIdentifier": "t_address_payable",
872 | "typeString": "address payable"
873 | }
874 | },
875 | "src": "150:18:3",
876 | "typeDescriptions": {
877 | "typeIdentifier": "t_address",
878 | "typeString": "address"
879 | }
880 | },
881 | "id": 423,
882 | "nodeType": "ExpressionStatement",
883 | "src": "150:18:3"
884 | }
885 | ]
886 | },
887 | "documentation": null,
888 | "id": 425,
889 | "implemented": true,
890 | "kind": "constructor",
891 | "modifiers": [],
892 | "name": "",
893 | "nodeType": "FunctionDefinition",
894 | "parameters": {
895 | "id": 417,
896 | "nodeType": "ParameterList",
897 | "parameters": [],
898 | "src": "134:2:3"
899 | },
900 | "returnParameters": {
901 | "id": 418,
902 | "nodeType": "ParameterList",
903 | "parameters": [],
904 | "src": "144:0:3"
905 | },
906 | "scope": 467,
907 | "src": "123:50:3",
908 | "stateMutability": "nonpayable",
909 | "superFunction": null,
910 | "visibility": "public"
911 | },
912 | {
913 | "body": {
914 | "id": 433,
915 | "nodeType": "Block",
916 | "src": "199:37:3",
917 | "statements": [
918 | {
919 | "condition": {
920 | "argumentTypes": null,
921 | "commonType": {
922 | "typeIdentifier": "t_address",
923 | "typeString": "address"
924 | },
925 | "id": 430,
926 | "isConstant": false,
927 | "isLValue": false,
928 | "isPure": false,
929 | "lValueRequested": false,
930 | "leftExpression": {
931 | "argumentTypes": null,
932 | "expression": {
933 | "argumentTypes": null,
934 | "id": 427,
935 | "name": "msg",
936 | "nodeType": "Identifier",
937 | "overloadedDeclarations": [],
938 | "referencedDeclaration": 482,
939 | "src": "209:3:3",
940 | "typeDescriptions": {
941 | "typeIdentifier": "t_magic_message",
942 | "typeString": "msg"
943 | }
944 | },
945 | "id": 428,
946 | "isConstant": false,
947 | "isLValue": false,
948 | "isPure": false,
949 | "lValueRequested": false,
950 | "memberName": "sender",
951 | "nodeType": "MemberAccess",
952 | "referencedDeclaration": null,
953 | "src": "209:10:3",
954 | "typeDescriptions": {
955 | "typeIdentifier": "t_address_payable",
956 | "typeString": "address payable"
957 | }
958 | },
959 | "nodeType": "BinaryOperation",
960 | "operator": "==",
961 | "rightExpression": {
962 | "argumentTypes": null,
963 | "id": 429,
964 | "name": "owner",
965 | "nodeType": "Identifier",
966 | "overloadedDeclarations": [],
967 | "referencedDeclaration": 414,
968 | "src": "223:5:3",
969 | "typeDescriptions": {
970 | "typeIdentifier": "t_address",
971 | "typeString": "address"
972 | }
973 | },
974 | "src": "209:19:3",
975 | "typeDescriptions": {
976 | "typeIdentifier": "t_bool",
977 | "typeString": "bool"
978 | }
979 | },
980 | "falseBody": null,
981 | "id": 432,
982 | "nodeType": "IfStatement",
983 | "src": "205:26:3",
984 | "trueBody": {
985 | "id": 431,
986 | "nodeType": "PlaceholderStatement",
987 | "src": "230:1:3"
988 | }
989 | }
990 | ]
991 | },
992 | "documentation": null,
993 | "id": 434,
994 | "name": "restricted",
995 | "nodeType": "ModifierDefinition",
996 | "parameters": {
997 | "id": 426,
998 | "nodeType": "ParameterList",
999 | "parameters": [],
1000 | "src": "196:2:3"
1001 | },
1002 | "src": "177:59:3",
1003 | "visibility": "internal"
1004 | },
1005 | {
1006 | "body": {
1007 | "id": 445,
1008 | "nodeType": "Block",
1009 | "src": "296:47:3",
1010 | "statements": [
1011 | {
1012 | "expression": {
1013 | "argumentTypes": null,
1014 | "id": 443,
1015 | "isConstant": false,
1016 | "isLValue": false,
1017 | "isPure": false,
1018 | "lValueRequested": false,
1019 | "leftHandSide": {
1020 | "argumentTypes": null,
1021 | "id": 441,
1022 | "name": "last_completed_migration",
1023 | "nodeType": "Identifier",
1024 | "overloadedDeclarations": [],
1025 | "referencedDeclaration": 416,
1026 | "src": "302:24:3",
1027 | "typeDescriptions": {
1028 | "typeIdentifier": "t_uint256",
1029 | "typeString": "uint256"
1030 | }
1031 | },
1032 | "nodeType": "Assignment",
1033 | "operator": "=",
1034 | "rightHandSide": {
1035 | "argumentTypes": null,
1036 | "id": 442,
1037 | "name": "completed",
1038 | "nodeType": "Identifier",
1039 | "overloadedDeclarations": [],
1040 | "referencedDeclaration": 436,
1041 | "src": "329:9:3",
1042 | "typeDescriptions": {
1043 | "typeIdentifier": "t_uint256",
1044 | "typeString": "uint256"
1045 | }
1046 | },
1047 | "src": "302:36:3",
1048 | "typeDescriptions": {
1049 | "typeIdentifier": "t_uint256",
1050 | "typeString": "uint256"
1051 | }
1052 | },
1053 | "id": 444,
1054 | "nodeType": "ExpressionStatement",
1055 | "src": "302:36:3"
1056 | }
1057 | ]
1058 | },
1059 | "documentation": null,
1060 | "id": 446,
1061 | "implemented": true,
1062 | "kind": "function",
1063 | "modifiers": [
1064 | {
1065 | "arguments": null,
1066 | "id": 439,
1067 | "modifierName": {
1068 | "argumentTypes": null,
1069 | "id": 438,
1070 | "name": "restricted",
1071 | "nodeType": "Identifier",
1072 | "overloadedDeclarations": [],
1073 | "referencedDeclaration": 434,
1074 | "src": "285:10:3",
1075 | "typeDescriptions": {
1076 | "typeIdentifier": "t_modifier$__$",
1077 | "typeString": "modifier ()"
1078 | }
1079 | },
1080 | "nodeType": "ModifierInvocation",
1081 | "src": "285:10:3"
1082 | }
1083 | ],
1084 | "name": "setCompleted",
1085 | "nodeType": "FunctionDefinition",
1086 | "parameters": {
1087 | "id": 437,
1088 | "nodeType": "ParameterList",
1089 | "parameters": [
1090 | {
1091 | "constant": false,
1092 | "id": 436,
1093 | "name": "completed",
1094 | "nodeType": "VariableDeclaration",
1095 | "scope": 446,
1096 | "src": "262:14:3",
1097 | "stateVariable": false,
1098 | "storageLocation": "default",
1099 | "typeDescriptions": {
1100 | "typeIdentifier": "t_uint256",
1101 | "typeString": "uint256"
1102 | },
1103 | "typeName": {
1104 | "id": 435,
1105 | "name": "uint",
1106 | "nodeType": "ElementaryTypeName",
1107 | "src": "262:4:3",
1108 | "typeDescriptions": {
1109 | "typeIdentifier": "t_uint256",
1110 | "typeString": "uint256"
1111 | }
1112 | },
1113 | "value": null,
1114 | "visibility": "internal"
1115 | }
1116 | ],
1117 | "src": "261:16:3"
1118 | },
1119 | "returnParameters": {
1120 | "id": 440,
1121 | "nodeType": "ParameterList",
1122 | "parameters": [],
1123 | "src": "296:0:3"
1124 | },
1125 | "scope": 467,
1126 | "src": "240:103:3",
1127 | "stateMutability": "nonpayable",
1128 | "superFunction": null,
1129 | "visibility": "public"
1130 | },
1131 | {
1132 | "body": {
1133 | "id": 465,
1134 | "nodeType": "Block",
1135 | "src": "403:109:3",
1136 | "statements": [
1137 | {
1138 | "assignments": [
1139 | 454
1140 | ],
1141 | "declarations": [
1142 | {
1143 | "constant": false,
1144 | "id": 454,
1145 | "name": "upgraded",
1146 | "nodeType": "VariableDeclaration",
1147 | "scope": 465,
1148 | "src": "409:19:3",
1149 | "stateVariable": false,
1150 | "storageLocation": "default",
1151 | "typeDescriptions": {
1152 | "typeIdentifier": "t_contract$_Migrations_$467",
1153 | "typeString": "contract Migrations"
1154 | },
1155 | "typeName": {
1156 | "contractScope": null,
1157 | "id": 453,
1158 | "name": "Migrations",
1159 | "nodeType": "UserDefinedTypeName",
1160 | "referencedDeclaration": 467,
1161 | "src": "409:10:3",
1162 | "typeDescriptions": {
1163 | "typeIdentifier": "t_contract$_Migrations_$467",
1164 | "typeString": "contract Migrations"
1165 | }
1166 | },
1167 | "value": null,
1168 | "visibility": "internal"
1169 | }
1170 | ],
1171 | "id": 458,
1172 | "initialValue": {
1173 | "argumentTypes": null,
1174 | "arguments": [
1175 | {
1176 | "argumentTypes": null,
1177 | "id": 456,
1178 | "name": "new_address",
1179 | "nodeType": "Identifier",
1180 | "overloadedDeclarations": [],
1181 | "referencedDeclaration": 448,
1182 | "src": "442:11:3",
1183 | "typeDescriptions": {
1184 | "typeIdentifier": "t_address",
1185 | "typeString": "address"
1186 | }
1187 | }
1188 | ],
1189 | "expression": {
1190 | "argumentTypes": [
1191 | {
1192 | "typeIdentifier": "t_address",
1193 | "typeString": "address"
1194 | }
1195 | ],
1196 | "id": 455,
1197 | "name": "Migrations",
1198 | "nodeType": "Identifier",
1199 | "overloadedDeclarations": [],
1200 | "referencedDeclaration": 467,
1201 | "src": "431:10:3",
1202 | "typeDescriptions": {
1203 | "typeIdentifier": "t_type$_t_contract$_Migrations_$467_$",
1204 | "typeString": "type(contract Migrations)"
1205 | }
1206 | },
1207 | "id": 457,
1208 | "isConstant": false,
1209 | "isLValue": false,
1210 | "isPure": false,
1211 | "kind": "typeConversion",
1212 | "lValueRequested": false,
1213 | "names": [],
1214 | "nodeType": "FunctionCall",
1215 | "src": "431:23:3",
1216 | "typeDescriptions": {
1217 | "typeIdentifier": "t_contract$_Migrations_$467",
1218 | "typeString": "contract Migrations"
1219 | }
1220 | },
1221 | "nodeType": "VariableDeclarationStatement",
1222 | "src": "409:45:3"
1223 | },
1224 | {
1225 | "expression": {
1226 | "argumentTypes": null,
1227 | "arguments": [
1228 | {
1229 | "argumentTypes": null,
1230 | "id": 462,
1231 | "name": "last_completed_migration",
1232 | "nodeType": "Identifier",
1233 | "overloadedDeclarations": [],
1234 | "referencedDeclaration": 416,
1235 | "src": "482:24:3",
1236 | "typeDescriptions": {
1237 | "typeIdentifier": "t_uint256",
1238 | "typeString": "uint256"
1239 | }
1240 | }
1241 | ],
1242 | "expression": {
1243 | "argumentTypes": [
1244 | {
1245 | "typeIdentifier": "t_uint256",
1246 | "typeString": "uint256"
1247 | }
1248 | ],
1249 | "expression": {
1250 | "argumentTypes": null,
1251 | "id": 459,
1252 | "name": "upgraded",
1253 | "nodeType": "Identifier",
1254 | "overloadedDeclarations": [],
1255 | "referencedDeclaration": 454,
1256 | "src": "460:8:3",
1257 | "typeDescriptions": {
1258 | "typeIdentifier": "t_contract$_Migrations_$467",
1259 | "typeString": "contract Migrations"
1260 | }
1261 | },
1262 | "id": 461,
1263 | "isConstant": false,
1264 | "isLValue": false,
1265 | "isPure": false,
1266 | "lValueRequested": false,
1267 | "memberName": "setCompleted",
1268 | "nodeType": "MemberAccess",
1269 | "referencedDeclaration": 446,
1270 | "src": "460:21:3",
1271 | "typeDescriptions": {
1272 | "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$",
1273 | "typeString": "function (uint256) external"
1274 | }
1275 | },
1276 | "id": 463,
1277 | "isConstant": false,
1278 | "isLValue": false,
1279 | "isPure": false,
1280 | "kind": "functionCall",
1281 | "lValueRequested": false,
1282 | "names": [],
1283 | "nodeType": "FunctionCall",
1284 | "src": "460:47:3",
1285 | "typeDescriptions": {
1286 | "typeIdentifier": "t_tuple$__$",
1287 | "typeString": "tuple()"
1288 | }
1289 | },
1290 | "id": 464,
1291 | "nodeType": "ExpressionStatement",
1292 | "src": "460:47:3"
1293 | }
1294 | ]
1295 | },
1296 | "documentation": null,
1297 | "id": 466,
1298 | "implemented": true,
1299 | "kind": "function",
1300 | "modifiers": [
1301 | {
1302 | "arguments": null,
1303 | "id": 451,
1304 | "modifierName": {
1305 | "argumentTypes": null,
1306 | "id": 450,
1307 | "name": "restricted",
1308 | "nodeType": "Identifier",
1309 | "overloadedDeclarations": [],
1310 | "referencedDeclaration": 434,
1311 | "src": "392:10:3",
1312 | "typeDescriptions": {
1313 | "typeIdentifier": "t_modifier$__$",
1314 | "typeString": "modifier ()"
1315 | }
1316 | },
1317 | "nodeType": "ModifierInvocation",
1318 | "src": "392:10:3"
1319 | }
1320 | ],
1321 | "name": "upgrade",
1322 | "nodeType": "FunctionDefinition",
1323 | "parameters": {
1324 | "id": 449,
1325 | "nodeType": "ParameterList",
1326 | "parameters": [
1327 | {
1328 | "constant": false,
1329 | "id": 448,
1330 | "name": "new_address",
1331 | "nodeType": "VariableDeclaration",
1332 | "scope": 466,
1333 | "src": "364:19:3",
1334 | "stateVariable": false,
1335 | "storageLocation": "default",
1336 | "typeDescriptions": {
1337 | "typeIdentifier": "t_address",
1338 | "typeString": "address"
1339 | },
1340 | "typeName": {
1341 | "id": 447,
1342 | "name": "address",
1343 | "nodeType": "ElementaryTypeName",
1344 | "src": "364:7:3",
1345 | "stateMutability": "nonpayable",
1346 | "typeDescriptions": {
1347 | "typeIdentifier": "t_address",
1348 | "typeString": "address"
1349 | }
1350 | },
1351 | "value": null,
1352 | "visibility": "internal"
1353 | }
1354 | ],
1355 | "src": "363:21:3"
1356 | },
1357 | "returnParameters": {
1358 | "id": 452,
1359 | "nodeType": "ParameterList",
1360 | "parameters": [],
1361 | "src": "403:0:3"
1362 | },
1363 | "scope": 467,
1364 | "src": "347:165:3",
1365 | "stateMutability": "nonpayable",
1366 | "superFunction": null,
1367 | "visibility": "public"
1368 | }
1369 | ],
1370 | "scope": 468,
1371 | "src": "34:480:3"
1372 | }
1373 | ],
1374 | "src": "0:515:3"
1375 | },
1376 | "compiler": {
1377 | "name": "solc",
1378 | "version": "0.5.16+commit.9c3226ce.Emscripten.clang"
1379 | },
1380 | "networks": {
1381 | "3": {
1382 | "events": {},
1383 | "links": {},
1384 | "address": "0xf8C2f0D155a34A705f125E3b1F952F696888FE17",
1385 | "transactionHash": "0x3a63d08bd186fb00b5c4e2857c97cb1340eb297038a5e4a754035d53d1a79346"
1386 | },
1387 | "1601483654711": {
1388 | "events": {},
1389 | "links": {},
1390 | "address": "0x2CbCAe09Fd1Affa06C732e54EEE6DdF183337472",
1391 | "transactionHash": "0x83c4a9f976a2a33bfa0ec8e4c8e26b28282eb239cef59206dbf6ce639db9ba0a"
1392 | },
1393 | "1601519134588": {
1394 | "events": {},
1395 | "links": {},
1396 | "address": "0xd0Ec6Ae91337DBa6f8f5ABC098F043bE8D3B3f47",
1397 | "transactionHash": "0x63e41e7d4cbbb12fb65f1a2026548759b7ee769c0258ff44030d4ac6e5bd7c1c"
1398 | },
1399 | "1601569818716": {
1400 | "events": {},
1401 | "links": {},
1402 | "address": "0x7E15d1a8f440eff84e1c798880cac14537A8fC20",
1403 | "transactionHash": "0xdd7e1f2a583bb251f266181f53ae7d7cc91af6779d3cba74f42d459e8bc16dd5"
1404 | },
1405 | "1601570969872": {
1406 | "events": {},
1407 | "links": {},
1408 | "address": "0x97E4Eb881cCeBb61a6bB31a37a8Ca0087bcaf704",
1409 | "transactionHash": "0xa6af48277cfe4ebd2cb213fb92a3f2011c3a83c6cc00b710f5c2bf9759b28d21"
1410 | },
1411 | "1601608424760": {
1412 | "events": {},
1413 | "links": {},
1414 | "address": "0x8CB25adCd621bf917e9B45524eee0630f1EFFbF8",
1415 | "transactionHash": "0x192245af10141edf208cb279e4f6c0477702d296234b5e74bde4f0ebd4238b3a"
1416 | },
1417 | "1601616853749": {
1418 | "events": {},
1419 | "links": {},
1420 | "address": "0xa667bB805cab820db8609621804A32d130C6FA18",
1421 | "transactionHash": "0x32ec55d5a5f902c27f88a82a2a5c57d9afa569c17ea86200522c6a9adbbd8514"
1422 | },
1423 | "1602082467755": {
1424 | "events": {},
1425 | "links": {},
1426 | "address": "0x4A2321CbCbDEee50F2463205f662CFD68E0C6776",
1427 | "transactionHash": "0xee95ba3db277b5c1cfc086af4795708a7cd03574029301cf44c6d58c76d845bd"
1428 | },
1429 | "1602138278662": {
1430 | "events": {},
1431 | "links": {},
1432 | "address": "0xa8A78B29e9f238CfA88bc403521104753Bb975c7",
1433 | "transactionHash": "0x3ca6b8e1b8ba7d0e6c61e1b4ed693fd6c5df31015f6060b61b97c96ecd4b803d"
1434 | },
1435 | "1602139313710": {
1436 | "events": {},
1437 | "links": {},
1438 | "address": "0x0Ca158fD73DE74e595172323Ab8711d7973493D6",
1439 | "transactionHash": "0xfc7741c958cb182f32e2a3174e2977b9c2f79fd6eba5b27d212e2b135cce64a8"
1440 | },
1441 | "1602140875825": {
1442 | "events": {},
1443 | "links": {},
1444 | "address": "0x76e5f191D86f0C2cCAd1204D8901aC595aC16829",
1445 | "transactionHash": "0xaf724837be2ae29eb5c577fd1094821f7531c9e790a1a4ccdae1201aca0be25e"
1446 | }
1447 | },
1448 | "schemaVersion": "3.2.5",
1449 | "updatedAt": "2020-10-08T07:50:30.164Z",
1450 | "networkType": "ethereum",
1451 | "devdoc": {
1452 | "methods": {}
1453 | },
1454 | "userdoc": {
1455 | "methods": {}
1456 | }
1457 | }
--------------------------------------------------------------------------------
/src/components/App.css:
--------------------------------------------------------------------------------
1 | /* Styles go here */
2 |
--------------------------------------------------------------------------------
/src/components/App.js:
--------------------------------------------------------------------------------
1 | import Decentragram from '../abis/Decentragram.json'
2 | import React, { Component } from 'react';
3 | import Identicon from 'identicon.js';
4 | import Navbar from './Navbar'
5 | import Main from './Main'
6 | import Web3 from 'web3';
7 | import './App.css';
8 |
9 | //Declare IPFS
10 | const ipfsClient = require('ipfs-http-client')
11 | const ipfs = ipfsClient({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' }) // leaving out the arguments will default to these values
12 |
13 | class App extends Component {
14 |
15 | async componentWillMount() {
16 | await this.loadWeb3()
17 | await this.loadBlockchainData()
18 | }
19 |
20 | async loadWeb3() {
21 | if (window.ethereum) {
22 | window.web3 = new Web3(window.ethereum)
23 | await window.ethereum.enable()
24 | }
25 | else if (window.web3) {
26 | window.web3 = new Web3(window.web3.currentProvider)
27 | }
28 | else {
29 | window.alert('Non-Ethereum browser detected. You should consider trying MetaMask!')
30 | }
31 | }
32 |
33 | async loadBlockchainData() {
34 | const web3 = window.web3
35 | // Load account
36 | const accounts = await web3.eth.getAccounts()
37 | this.setState({ account: accounts[0] })
38 | // Network ID
39 | const networkId = await web3.eth.net.getId()
40 | const networkData = Decentragram.networks[networkId]
41 | if(networkData) {
42 | const decentragram = new web3.eth.Contract(Decentragram.abi, networkData.address)
43 | this.setState({ decentragram })
44 | const imagesCount = await decentragram.methods.imageCount().call()
45 | this.setState({ imagesCount })
46 | // Load images
47 | for (var i = 1; i <= imagesCount; i++) {
48 | const image = await decentragram.methods.images(i).call()
49 | this.setState({
50 | images: [...this.state.images, image]
51 | })
52 | }
53 | // Sort images. Show highest tipped images first
54 | this.setState({
55 | images: this.state.images.sort((a,b) => b.tipAmount - a.tipAmount )
56 | })
57 | this.setState({ loading: false})
58 | } else {
59 | window.alert('Decentragram contract not deployed to detected network.')
60 | }
61 | }
62 |
63 | captureFile = event => {
64 |
65 | event.preventDefault()
66 | const file = event.target.files[0]
67 | const reader = new window.FileReader()
68 | reader.readAsArrayBuffer(file)
69 |
70 | reader.onloadend = () => {
71 | this.setState({ buffer: Buffer(reader.result) })
72 | console.log('buffer', this.state.buffer)
73 | }
74 | }
75 |
76 | uploadImage = description => {
77 | console.log("Submitting file to ipfs...")
78 |
79 | //adding file to the IPFS
80 | ipfs.add(this.state.buffer, (error, result) => {
81 | console.log('Ipfs result', result)
82 | if(error) {
83 | console.error(error)
84 | return
85 | }
86 |
87 | this.setState({ loading: true })
88 | this.state.decentragram.methods.uploadImage(result[0].hash, description).send({ from: this.state.account }).on('transactionHash', (hash) => {
89 | this.setState({ loading: false })
90 | })
91 | })
92 | }
93 |
94 | tipImageOwner(id, tipAmount) {
95 | this.setState({ loading: true })
96 | this.state.decentragram.methods.tipImageOwner(id).send({ from: this.state.account, value: tipAmount }).on('transactionHash', (hash) => {
97 | this.setState({ loading: false })
98 | })
99 | }
100 |
101 | constructor(props) {
102 | super(props)
103 | this.state = {
104 | account: '',
105 | decentragram: null,
106 | images: [],
107 | loading: true
108 | }
109 |
110 | this.uploadImage = this.uploadImage.bind(this)
111 | this.tipImageOwner = this.tipImageOwner.bind(this)
112 | this.captureFile = this.captureFile.bind(this)
113 | }
114 |
115 | render() {
116 | return (
117 |
118 |
119 | { this.state.loading
120 | ?
121 | :
127 | }
128 |
129 | );
130 | }
131 | }
132 |
133 | export default App;
--------------------------------------------------------------------------------
/src/components/Main.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Identicon from 'identicon.js';
3 |
4 | class Main extends Component {
5 |
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
Share Image
14 |
32 |
33 | { this.props.images.map((image, key) => {
34 | return(
35 |
36 |
37 |

43 |
{image.author}
44 |
45 |
46 | -
47 |

48 | {image.description}
49 |
50 | -
51 |
52 | TIPS: {window.web3.utils.fromWei(image.tipAmount.toString(), 'Ether')} ETH
53 |
54 |
65 |
66 |
67 |
68 | )
69 | })}
70 |
71 |
72 |
73 |
74 | );
75 | }
76 | }
77 |
78 | export default Main;
--------------------------------------------------------------------------------
/src/components/Navbar.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Identicon from 'identicon.js';
3 | import photo from '../photo.png'
4 |
5 | class Navbar extends Component {
6 |
7 | render() {
8 | return (
9 |
37 | );
38 | }
39 | }
40 |
41 | export default Navbar;
--------------------------------------------------------------------------------
/src/contract/Crytogram.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.0;
2 |
3 | contract Cryptogram {
4 | string public name;
5 | uint public imageCount = 0;
6 | mapping(uint => Image) public images;
7 |
8 | struct Image {
9 | uint id;
10 | string hash;
11 | string description;
12 | uint tipAmount;
13 | address payable author;
14 | }
15 |
16 | event ImageCreated(
17 | uint id,
18 | string hash,
19 | string description,
20 | uint tipAmount,
21 | address payable author
22 | );
23 |
24 | event ImageTipped(
25 | uint id,
26 | string hash,
27 | string description,
28 | uint tipAmount,
29 | address payable author
30 | );
31 |
32 | constructor() public {
33 | name = "Cryptogram";
34 | }
35 |
36 | function uploadImage(string memory _imgHash, string memory _description) public {
37 | // Make sure the image hash exists
38 | require(bytes(_imgHash).length > 0);
39 | // Make sure image description exists
40 | require(bytes(_description).length > 0);
41 | // Make sure uploader address exists
42 | require(msg.sender!=address(0));
43 |
44 | // Increment image id
45 | imageCount ++;
46 |
47 | // Add Image to the contract
48 | images[imageCount] = Image(imageCount, _imgHash, _description, 0, msg.sender);
49 | // Trigger an event
50 | emit ImageCreated(imageCount, _imgHash, _description, 0, msg.sender);
51 | }
52 |
53 | function tipImageOwner(uint _id) public payable {
54 | // Make sure the id is valid
55 | require(_id > 0 && _id <= imageCount);
56 | // Fetch the image
57 | Image memory _image = images[_id];
58 | // Fetch the author
59 | address payable _author = _image.author;
60 | // Pay the author by sending them Ether
61 | address(_author).transfer(msg.value);
62 | // Increment the tip amount
63 | _image.tipAmount = _image.tipAmount + msg.value;
64 | // Update the image
65 | images[_id] = _image;
66 | // Trigger an event
67 | emit ImageTipped(_id, _image.hash, _image.description, _image.tipAmount, _author);
68 | }
69 | }
--------------------------------------------------------------------------------
/src/cryptologo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AchyuthMohan/Blockchain-Cryptogram/1131b4421f5db99f3a21a63894f0e7e3793a0820/src/cryptologo.png
--------------------------------------------------------------------------------
/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/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AchyuthMohan/Blockchain-Cryptogram/1131b4421f5db99f3a21a63894f0e7e3793a0820/src/logo.png
--------------------------------------------------------------------------------
/src/photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AchyuthMohan/Blockchain-Cryptogram/1131b4421f5db99f3a21a63894f0e7e3793a0820/src/photo.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | const Decentragram = artifacts.require('./Decentragram.sol')
2 |
3 | require('chai')
4 | .use(require('chai-as-promised'))
5 | .should()
6 |
7 | contract('Decentragram', ([deployer, author, tipper]) => {
8 | let decentragram
9 |
10 | before(async () => {
11 | decentragram = await Decentragram.deployed()
12 | })
13 |
14 | describe('deployment', async () => {
15 | it('deploys successfully', async () => {
16 | const address = await decentragram.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 decentragram.name()
25 | assert.equal(name, 'Decentragram')
26 | })
27 | })
28 |
29 | describe('images', async () => {
30 | let result, imageCount
31 | const hash = 'QmV8cfu6n4NT5xRr2AHdKxFMTZEJrA44qgrBCr739BN9Wb'
32 |
33 | before(async () => {
34 | result = await decentragram.uploadImage(hash, 'Image description', { from: author })
35 | imageCount = await decentragram.imageCount()
36 | })
37 |
38 | //check event
39 | it('creates images', async () => {
40 | // SUCESS
41 | assert.equal(imageCount, 1)
42 | const event = result.logs[0].args
43 | assert.equal(event.id.toNumber(), imageCount.toNumber(), 'id is correct')
44 | assert.equal(event.hash, hash, 'Hash is correct')
45 | assert.equal(event.description, 'Image description', 'description is correct')
46 | assert.equal(event.tipAmount, '0', 'tip amount is correct')
47 | assert.equal(event.author, author, 'author is correct')
48 |
49 |
50 | // FAILURE: Image must have hash
51 | await decentragram.uploadImage('', 'Image description', { from: author }).should.be.rejected;
52 |
53 | // FAILURE: Image must have description
54 | await decentragram.uploadImage('Image hash', '', { from: author }).should.be.rejected;
55 | })
56 |
57 | //check from Struct
58 | it('lists images', async () => {
59 | const image = await decentragram.images(imageCount)
60 | assert.equal(image.id.toNumber(), imageCount.toNumber(), 'id is correct')
61 | assert.equal(image.hash, hash, 'Hash is correct')
62 | assert.equal(image.description, 'Image description', 'description is correct')
63 | assert.equal(image.tipAmount, '0', 'tip amount is correct')
64 | assert.equal(image.author, author, 'author is correct')
65 | })
66 |
67 | it('allows users to tip images', async () => {
68 | // Track the author balance before purchase
69 | let oldAuthorBalance
70 | oldAuthorBalance = await web3.eth.getBalance(author)
71 | oldAuthorBalance = new web3.utils.BN(oldAuthorBalance)
72 |
73 | result = await decentragram.tipImageOwner(imageCount, { from: tipper, value: web3.utils.toWei('1', 'Ether') })
74 |
75 | // SUCCESS
76 | const event = result.logs[0].args
77 | assert.equal(event.id.toNumber(), imageCount.toNumber(), 'id is correct')
78 | assert.equal(event.hash, hash, 'Hash is correct')
79 | assert.equal(event.description, 'Image description', 'description is correct')
80 | assert.equal(event.tipAmount, '1000000000000000000', 'tip amount is correct')
81 | assert.equal(event.author, author, 'author is correct')
82 |
83 | // Check that author received funds
84 | let newAuthorBalance
85 | newAuthorBalance = await web3.eth.getBalance(author)
86 | newAuthorBalance = new web3.utils.BN(newAuthorBalance)
87 |
88 | let tipImageOwner
89 | tipImageOwner = web3.utils.toWei('1', 'Ether')
90 | tipImageOwner = new web3.utils.BN(tipImageOwner)
91 |
92 | const expectedBalance = oldAuthorBalance.add(tipImageOwner)
93 |
94 | assert.equal(newAuthorBalance.toString(), expectedBalance.toString())
95 |
96 | // FAILURE: Tries to tip a image that does not exist
97 | await decentragram.tipImageOwner(99, { from: tipper, value: web3.utils.toWei('1', 'Ether')}).should.be.rejected;
98 | })
99 | })
100 | })
--------------------------------------------------------------------------------
/truffle-config.js:
--------------------------------------------------------------------------------
1 | require('babel-register');
2 | require('babel-polyfill');
3 | require('dotenv').config();
4 | const HDWalletProvider = require('truffle-hdwallet-provider-privkey');
5 | const privateKeys = process.env.PRIVATE_KEYS || ""
6 |
7 | module.exports = {
8 | networks: {
9 | development: {
10 | host: "127.0.0.1",
11 | port: 7545,
12 | network_id: "*" // Match any network id
13 | },
14 | ropsten: {
15 | provider: function() {
16 | return new HDWalletProvider(
17 | privateKeys.split(','), // Array of account private keys
18 | `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}`// Url to an Ethereum Node
19 | )
20 | },
21 | gas: 5000000,
22 | gasPrice: 25000000000,
23 | network_id: 3
24 | }
25 | },
26 | contracts_directory: './src/contracts/',
27 | contracts_build_directory: './src/abis/',
28 | compilers: {
29 | solc: {
30 | optimizer: {
31 | enabled: true,
32 | runs: 200
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------