-
Notifications
You must be signed in to change notification settings - Fork 59
/
storage.html
executable file
·214 lines (183 loc) · 8.85 KB
/
storage.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<!doctype>
<html>
<head>
<title>IPFS + Ethereum Storage Application</title>
<link rel="stylesheet" type="text/css" href="./storage/style.css" />
<script type="text/javascript" src="./ipfs/ipfs.js"></script>
<script type="text/javascript" src="./web3/web3.min.js"></script>
<script type="text/javascript">
/* Configuration variables */
var ipfsHost = 'localhost';
var ipfsAPIPort = '5001';
var ipfsWebPort = '8080';
var web3Host = 'http://localhost';
var web3Port = '8545';
/* IPFS initialization */
var ipfs = window.IpfsApi(ipfsHost, ipfsAPIPort)
ipfs.swarm.peers(function (err, res) {
if (err) {
console.error(err);
} else {
var numPeers = res.Peers === null ? 0 : res.Peers.length;
console.log("IPFS - connected to " + numPeers + " peers");
}
});
/* web3 initialization */
var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider(web3Host + ':' + web3Port));
if (!web3.isConnected()) {
console.error("Ethereum - no connection to RPC server");
} else {
console.log("Ethereum - connected to RPC server");
}
/* JavaScript smart contract interface */
var contractInterface = [{
"constant": false,
"inputs": [{
"name": "x",
"type": "string"
}],
"name": "set",
"outputs": [],
"type": "function"
}, {
"constant": true,
"inputs": [],
"name": "get",
"outputs": [{
"name": "x",
"type": "string"
}],
"type": "function"
}];
var account = web3.eth.accounts[0];
var contractObject = {
from: account,
gas: 300000,
data: '0x6060604052610282806100126000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480634ed3885e146100445780636d4ce63c1461009a57610042565b005b6100986004808035906020019082018035906020019191908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050909091905050610115565b005b6100a760048050506101c6565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101075780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061016457805160ff1916838001178555610195565b82800160010185558215610195579182015b82811115610194578251826000505591602001919060010190610176565b5b5090506101c091906101a2565b808211156101bc57600081815060009055506001016101a2565b5090565b50505b50565b602060405190810160405280600081526020015060006000508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102735780601f1061024857610100808354040283529160200191610273565b820191906000526020600020905b81548152906001019060200180831161025657829003601f168201915b5050505050905061027f565b9056'
};
var sendDataObject = {
from: account,
gas: 300000,
};
window.ipfs = ipfs;
window.web3 = web3;
window.account = account;
window.contractObject = contractObject;
window.contract = web3.eth.contract(contractInterface);
window.ipfsAddress = "http://" + ipfsHost + ':' + ipfsWebPort + "/ipfs";
function deployStorage() {
window.IPFSHash = null;
window.currentData = null;
if (window.contractInstance) {
console.error('Contract already been deployed at: ', window.contractAddress);
return;
}
window.contract.new(window.contractObject, function (err, contract) {
if (err) {
console.error("Contract deployment error: ", err);
} else if (contract.address) {
window.contractAddress = contract.address;
window.contractInstance = window.contract.at(contract.address);
console.log("Contract successfully deployed at: ", contract.address);
} else if (contract.transactionHash) {
console.log("Awaiting contract deployment with transaction hash: ", contract.transactionHash);
} else {
console.error("Unresolved contract deployment error");
}
});
}
function storeContent(url) {
window.ipfs.add(url, function(err, result) {
if (err) {
console.error("Content submission error:", err);
return false;
} else if (result && result[0] && result[0].Hash) {
console.log("Content successfully stored. IPFS address:", result[0].Hash);
} else {
console.error("Unresolved content submission error");
return null;
}
});
}
function storeAddress(data) {
if (!window.contractInstance) {
console.error('Ensure the storage contract has been deployed');
return;
}
if (window.currentData == data) {
console.error("Overriding existing data with same data");
return;
}
window.contractInstance.set.sendTransaction(data, window.sendDataObject, function (err, result) {
if (err) {
console.error("Transaction submission error:", err);
} else {
window.currentData = data;
console.log("Address successfully stored. Transaction hash:", result);
}
});
}
function fetchContent() {
if (!window.contractInstance) {
console.error("Storage contract has not been deployed");
return;
}
window.contractInstance.get.call(function (err, result) {
if (err) {
console.error("Content fetch error:", err);
} else if (result && window.IPFSHash == result) {
console.log("New data is not mined yet. Current data: ", result);
return;
} else if (result) {
window.IPFSHash = result;
var URL = window.ipfsAddress + "/" + result;
console.log("Content successfully retrieved. IPFS address", result);
console.log("Content URL:", URL);
} else {
console.error('No data, verify the transaction has been mined');
}
});
}
function getBalance() {
window.web3.eth.getBalance(window.account, function (err, balance) {
console.log(parseFloat(window.web3.fromWei(balance, "ether")));
});
}
</script>
</head>
<body>
<br/>
<h2>IPFS + Ethereum Storage Application</h2>
<hr/>
<br/>
<p>Start by opening the developer console to interact with the application. Verify that the console shows we are connect to our IPFS and geth clients. The following steps will guide you through setting up and operating our data storage solution using IPFS and Ethereum.</p>
<ol>
<li><code>deployStorage()</code>: Deploy the storage contract to your Ethereum blockchain. The geth client will show it received the deployment transaction, return a transaction hash to the console, and print out the contract transaction address after successful deployment.</li>
<br/>
<li><code>storeContent(URL)</code>: Store the specified URL content to IPFS. The IPFS client will receive the URL content for storage and return an IPFS address that will be provided to the smart contract.</li>
<br/>
<li><code>storeAddress(IPFS address)</code>: Submit a transaction to the Ethereum contract for storage on our blockchain.</li>
<br/>
<li><code>fetchContent()</code>: Gets the last stored IPFS address in the Ethereum contract and queries IPFS for the associated URL.</li>
</ol>
<br/>
<hr/>
<br/>
<p>Here is a concrete example. Let's say we want to upload an image of the <a href="https://ethereum.org/images/wallpaper-homestead.jpg">Ethereum Homestead wallpaper</a>. For example purposes, my IPFS hash address for this wallpaper resolves to "QmPJLNMiAp3QoCKdGAgzshNRbQiZ8wQmyjYkcUHJZzQ19u". Then we have all the pieces to run the storage application.</p>
<p>Run the commands:</p>
<ol>
<li><code>deployStorage()</code></li>
<li><code>storeContent("https://ethereum.org/images/wallpaper-homestead.jpg")</code></li>
<li><code>storeAddress("QmPJLNMiAp3QoCKdGAgzshNRbQiZ8wQmyjYkcUHJZzQ19u")</code></li>
<li><code>fetchContent()</code></li>
</ol>
<p>This process will then return: "http://localhost:8080/ipfs/QmPJLNMiAp3QoCKdGAgzshNRbQiZ8wQmyjYkcUHJZzQ19u"</p>
<br/>
<hr/>
<br/>
<p>Troubleshooting: To verify there is a positive ether balance, run <code>getBalance()</code> to check the Ethereum wallet balance.</p>
<br/>
<hr/>
</body>