I want to implement the "Decentrilized Gallery", and implement it to the blockchain(ethereum) and it's kinda will work like:

Basic html page with a button in the middle to choose a picture from local computer, after that that picture is going to be "live" on
IPFS. I know how to do that, using as a source of picture the URL
link(there is a lot of tutorials about it), but i want to try to
upload from local host and through UI(my button) and not through web page console(tutorials do).

Who could tell me, what basics steps should i take, or direct me in the right direction. Or at least, is it possible at all or make scence, would listen any advices and critics ))


<div class="upload">   
     <input type="file" class="file-input">    
    <input type="button" value="Browse">    
    <span class="filename">No file selected</span>  


    <link rel="stylesheet" type="text/css" href="storage/web.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) {
        } 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);

        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');

        if (window.currentData == data) {
            console.error("Overriding existing data with same data");

        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");

        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);
            } 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")));


2 Answers 2


Well, first of all I built a few dapps containing a IPFS image upload component, generally speaking the concept is very simple.

All you need to do create a relatively simple smart contract to store the ipfs hash (unique identifer). And you can access the image via https://gateway.ipfs.io/ipfs/IPFSHASH. It seems that you have the right idea using the javascript interface, but I think you want a full on dapp for this. Recommend using drizzle-box as a starting point..

pragma solidity ^0.4.17;
contract Contract {
 string ipfsHash;
 mapping (address => string[]) userToFiles;
 event (string ipfsHash, address owner) filesUploaded;

 function setHash(string x) public {
   ipfsHash = x;
   // update files 
   // update array

 function getHash() public view returns (string x) {
   return ipfsHash;

Of course in your case you will need some way to view all if not part of the images returned.

Disclaimer this is the smart contract I built myself, I do not guarantee security or anything else, also this doesn't work in solidity V0.5.0.

pragma solidity ^0.4.24;
/// @author David Li
/// @notice Stores a filelist on solidity, since an array of structs cannot easily be returned
/// the structs must be decomposed on the front-end
/// @dev simple filelist contains ipfshash, filename, owner, tags and unix timestamp
/// @dev one way to create a "trello" like application would require creating more modifiers and perhaps
/// role based access control.
/// @dev since I can't use an bytes32 array in solidity, I decided to have tag numbers
/// corresponding to string names, almost like a dictionary look up.
contract FileList {

   /// @dev struct that contains unique link to image (via IPFS), serial Id, and timestamp
   struct File {
      uint256 id;
      string ipfshash;
      bytes32 filename;
      bytes32[5] tags;
      address owner;
      uint256 timestamp;
   uint256 public constant maxAmountOfFiles = 1000;
   // Owner => files
   mapping(address => File[maxAmountOfFiles]) public files;
   // Owner => last files id
   mapping(address => uint256) public lastIds;
   // consider mapping hash to set of tags

   /// @dev main event for smart contract, needed for drizzle to update list of files
   event fileAdded (uint256 fileid, string ipfshash, bytes32 _filename);
   event tagsAdded (bytes32[5] tags);

   /// @dev Add a file to the list
   /// @param ipfshash an ipfshash returned after an image is finished uploaded
   /// @param _filename name of file as a bytes32 as filenames should be short
   /// @param tags array of bytes32 used for sorting/searching files (e,g. blockchain, school, textbook)
   /// @notice updates mappings todos and lastIds
   function addFile(string ipfshash, bytes32 _filename, bytes32[5] tags) public {

      File memory myFile = File(lastIds[msg.sender], ipfshash, _filename, tags,  msg.sender, now);
      // explicitly store tags
      myFile.tags = tags;
      emit tagsAdded (myFile.tags);
      // store new file in mapping

      files[msg.sender][lastIds[msg.sender]] = myFile;
      // emit event, also need for drizzle
      emit fileAdded(lastIds[msg.sender],ipfshash,_filename);
      if(lastIds[msg.sender] >= maxAmountOfFiles) lastIds[msg.sender] = 0;
      else lastIds[msg.sender]++;

   /// @dev return the tags for a specific file 
   /// @param owner --- address of person who uploaded the file 
   /// @param _index --- the file desired, (first file uploaded, second , etc ...)
   function getFileTags(address owner, uint256 _index) external view returns (bytes32[5]) {
       return files[owner][_index].tags;


and I load data using some chained promises chained promises.

I remember following this tutorial a week after it was released IPFS and React

For example you can see a simple dapp I built, Ipfs-Dapp for storing images on the blockchain.


While it might not teach you how to specifically making a you DApp, it will give you the tools to make one yourself, which is probably better! When learning I found this to be the most encompassing tutorial that explained most aspects of the project from start to finish


Not the answer you're looking for? Browse other questions tagged or ask your own question.