├── .github └── workflows │ ├── generated-pr.yml │ └── stale.yml ├── .gitignore ├── README.md ├── SUMMARY.md ├── avenues-for-access ├── README.md └── lessons │ ├── browser-extension.md │ ├── power-of-content-addressing.md │ ├── sneakernets.md │ ├── tor-gateways.md │ └── tor-transport.md ├── build-book.sh ├── classical-web ├── README.md └── lessons │ ├── local-gateway.md │ ├── other-gateways.md │ └── public-gateways.md ├── dynamic-content └── README.md ├── files-on-ipfs ├── README.md └── lessons │ ├── add-and-retrieve-file-content.md │ ├── pin-files.md │ └── wrap-directories-around-content.md ├── going-online ├── README.md └── lessons │ ├── connect-your-node.md │ ├── find-peers.md │ └── retrieve-from-peer.md ├── images └── railsbridge-format.png ├── install-ipfs ├── README.md └── lessons │ ├── download-and-install.md │ └── initialize-repository.md ├── ipfs-dag ├── README.md └── lessons │ ├── blocks-from-scratch.md │ ├── crypto-hash.md │ ├── files-as-dags.md │ └── hash-tree.png ├── publishing-changes ├── README.md └── lessons │ ├── create-webpage.md │ ├── generate-keypair.md │ ├── modify-republish.md │ ├── trains.jpg │ ├── view-and-publish.md │ └── webpage4.png ├── samples ├── sample-text-file.txt └── tree-in-cosmos.jpg └── styles └── website.css /.github/workflows/generated-pr.yml: -------------------------------------------------------------------------------- 1 | name: Close Generated PRs 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | workflow_dispatch: 7 | 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | 12 | jobs: 13 | stale: 14 | uses: ipdxco/unified-github-workflows/.github/workflows/reusable-generated-pr.yml@v1 15 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Close Stale Issues 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | workflow_dispatch: 7 | 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | 12 | jobs: 13 | stale: 14 | uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _book 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The IPFS Primer 2 | 3 | This primer contains a series of tutorials explaining IPFS, Merkle Trees and the Decentralized Web. It's written and maintained as a [gitbook](https://www.gitbook.com/about) so people can read it in many formats. 4 | 5 | The GitHub repository for this book is at https://github.com/ipfs-shipyard/ipfs-primer. 6 | 7 | # Getting Help 8 | 9 | During these tutorials, if you have any questions feel free to ask them in [the IPFS forums](https://discuss.ipfs.io) or in [the #ipfs channel on chat.freenode.net](irc://chat.freenode.net/%23ipfs). We have a large, active community who use these venues as our main places to seek support and to provide it. 10 | 11 | ## Tutorials 12 | 13 | The primer contains tutorials about 14 | 15 | 1. [Downloading and Installing IPFS](install-ipfs/README.md) 16 | 2. [Files on IPFS](files-on-ipfs/README.md) 17 | 3. [Going Online - Joining the Distributed Web](going-online/README.md) 18 | 4. [Interacting with the Classical (HTTP) Web](classical-web/README.md) 19 | 5. [The Myriad ways to Access and Distribute IPFS Content](avenues-for-access/README.md) 20 | 6. [Making Changes on the Permanent Web](publishing-changes/README.md) 21 | 7. [Merkle Trees and the IPFS DAG](ipfs-dag/README.md) 22 | 8. [Dynamic Content on IPFS](dynamic-content/README.md) 23 | 24 | For a full list of tutorials, look at the [Table of Contents](SUMMARY.md). 25 | 26 | ## Concepts 27 | 28 | * Cryptographic Hashes and Content Addressability 29 | * Authenticated Graphs 30 | * Turning Files into Trees 31 | * Turning any Data into Trees 32 | * Publishing hashes on the DHT 33 | * Getting data from the Peer to Peer Network 34 | * Immutability: "Changes" as _additions_ to the tree 35 | * CRDTs 36 | * Pubsub 37 | * Authenticated Streams (with pubsub) 38 | 39 | ## Format 40 | 41 | Each tutorial is a set of *lessons* that all use a format inspired by the [Railsbridge Curriculum](http://curriculum.railsbridge.org/intro-to-rails/). Each lesson declares a set of *Goals*, or [learning objectives](http://edglossary.org/learning-objectives/), then lists the *Steps*, or activities, and finally provides an *Explanation* that reviews what you've done and connects those activities to the lesson's stated Goals. The format for each lesson looks like this: 42 | 43 | ![Sample of Railsbridge Lesson format](/images/railsbridge-format.png) 44 | 45 | ## Note for Contributors 46 | 47 | For a concise explanation of Learning Objectives (which we're calling _Goals_ in this book), read UC Denver's [Assessment & Instructional Alignment Tutorial](http://www.ucdenver.edu/faculty_staff/faculty/center-for-faculty-development/Documents/tutorials/Assessment/module3/index.htm). Try to make your learning objectives [Specific, observable and measurable](http://www.ucdenver.edu/faculty_staff/faculty/center-for-faculty-development/Documents/tutorials/Assessment/module3/good_objectives.htm) and heed their tip to use the list of verbs in the [taxonomy table worksheet](http://www.ucdenver.edu/faculty_staff/faculty/center-for-faculty-development/Documents/tutorials/Assessment/documents/examples_verbs_cognitive_process_level.pdf) to help you choose observable behaviors for your course learning objectives. 48 | 49 | To build the HTML, PDF, epub and mobi versions of the book with one command, run `./build-book.sh` 50 | 51 | # Contributors 52 | 53 | This primer was created by @flyingzumwalt. The contents of these tutorials were initially pulled from documentation in the first-generation documentation homed on the IPFS website and the (now-inactive) IPFS examples git repository. (Find them in their new homes on [docs.ipfs.io](https://docs.ipfs.io), particularly the ["Usage ideas and examples"](https://docs.ipfs.io/concepts/usage-ideas-examples/) section.) 54 | 55 | Contributors to those original docs included 56 | * @whyrusleeping 57 | * @jbenet 58 | * @lgierth 59 | * @lynnandtonic 60 | * @wraithgar 61 | * @adambrault 62 | * @donothesitate 63 | * @djdv 64 | plus a long list of [contributors](https://github.com/ipfs/examples/network/members) to the original examples repository 65 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [Tutorial: Install and Initialize IPFS](/install-ipfs/README.md) 4 | * [Lesson: Download and Install IPFS](/install-ipfs/lessons/download-and-install.md) 5 | * [Lesson: Initialize your IPFS Repository](/install-ipfs/lessons/initialize-repository.md) 6 | 7 | * [Tutorial: Files on IPFS](/files-on-ipfs/README.md) 8 | * [Lesson: Add Content to IPFS and Retrieve It](/files-on-ipfs/lessons/add-and-retrieve-file-content.md) 9 | * [Lesson: Wrap Filenames and Directory Info around Content](/files-on-ipfs/lessons/wrap-directories-around-content.md) 10 | * [Lesson: Pinning - Tell IPFS to Keep a File](/files-on-ipfs/lessons/pin-files.md) 11 | 12 | * [Tutorial: Going Online - Joining the Distributed Web](/going-online/README.md) 13 | * [Lesson: Connect your node to the IPFS network](/going-online/lessons/connect-your-node.md) 14 | * [Lesson: Find Peers on the Network](/going-online/lessons/find-peers.md) 15 | * [Lesson: Retrieve content from a Peer](/going-online/lessons/retrieve-from-peer.md) 16 | 17 | * [Tutorial: Interacting with the Classical (HTTP) Web](/classical-web/README.md) 18 | * [Lesson: Use an HTTP browser to retrieve files from local IPFS gateway](/classical-web/lessons/local-gateway.md) 19 | * [Lesson: Get content through the public ipfs.io gateway](/classical-web/lessons/public-gateways.md) 20 | * [Lesson: Access IPFS content through any IPFS gateway](/classical-web/lessons/other-gateways.md) 21 | 22 | * [Tutorial: The Myriad ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) 23 | * [The Power of Content-addressing](/avenues-for-access/lessons/power-of-content-addressing.md) 24 | * [Retrieving content from a peer](/going-online/lessons/retrieve-from-peer.md) 25 | * Review these lessons from the Tutorial on Interacting with the Classical (HTTP) Web 26 | * [Review: Using an HTTP browser to retrieve files from local IPFS gateway](/classical-web/lessons/local-gateway.md) 27 | * [Review: Using the public IPFS gateways at ipfs.io](/classical-web/lessons/public-gateways.md) 28 | * [Review: Access IPFS content through any IPFS gateway](/aclassical-web/lessons/other-gateways.md) 29 | * [Lesson: Access IPFS content through Tor gateways (experimental)](/avenues-for-access/lessons/tor-gateways.md) 30 | * [Lesson: Run IPFS over Tor transport (experimental)](/avenues-for-access/lessons/tor-transport.md) 31 | * [Lesson: Access IPFS content through a browser extension](/avenues-for-access/lessons/browser-extension.md) 32 | * [Lesson: Sneakernets - moving the data on USB Drives and other Hardware](/avenues-for-access/lessons/sneakernets.md) 33 | 34 | * [Tutorial: Making Changes on the Permanent Web](publishing-changes/README.md) 35 | * [Lesson: Create a Simple Webpage and Add It to IPFS](publishing-changes/lessons/create-webpage.md) 36 | * [Lesson: View Your Webpage with IPFS and Publish to IPNS](publishing-changes/lessons/view-and-publish.md) 37 | * [Lesson: Modify Your Webpage and Republish to IPNS](publishing-changes/lessons/modify-republish.md) 38 | * [Lesson: Generate and Use a New IPNS Name Keypair](publishing-changes/lessons/generate-keypair.md) 39 | 40 | * [Tutorial: Merkle Trees and the IPFS DAG](ipfs-dag/README.md) 41 | * [Lesson: Turn a File into a Tree of Hashes](/ipfs-dag/lessons/files-as-dags.md) 42 | * [Lesson: The Cryptographic Hash](/ipfs-dag/lessons/crypto-hash.md) 43 | * [Lesson: Build a Tree of Data in IPFS Using Cryptographic Hashes to Link the Pieces (a Merkle DAG)](/ipfs-dag/lessons/blocks-from-scratch.md) 44 | * Lesson: Explore the types of software that use hash trees to track data *(to come)* 45 | 46 | * [Tutorial: Dynamic Content on IPFS](/dynamic-content/README.md) 47 | * Disclaimer: Dynamic content on IPFS is a Work in Progress *(to come)* 48 | * Lesson: Add data to the DAG (locally) *(to come)* 49 | * Lesson: Tell peers about your Changes *(to come)* 50 | * Lesson: Use hashes to get someone's changes from IPFS *(to come)* 51 | * Lesson: Use a pub/sub strategy to pass around messages about changes *(to come)* 52 | * Lesson: Resolve conflicts with a merge strategy (CRDTs) *(to come)* 53 | 54 | * Privacy and Access Controls on the Distributed Web *(to come)* 55 | * Reader Privacy & Writer Privacy *(to come)* 56 | * Private Networks *(to come)* 57 | * Encrypting Content *(to come)* 58 | * More dynamic encryption: capabilities-based encryption *(to come)* 59 | * Comparing with the classic HTTP web (feudal security, etc) *(to come)* 60 | 61 | * Keeping Data Alive: Durable Data on the Permanent Web *(to come)* 62 | * IPFS Cluster *(to come)* 63 | * Filecoin *(to come)* 64 | 65 | * Distributed Computation *(to come)* 66 | -------------------------------------------------------------------------------- /avenues-for-access/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: The Myriad Ways to Access and Distribute IPFS Content 2 | These Lessons are tested with go-ipfs version 0.5.0. _Please update this file on github to reflect any other versions that have been tested._ 3 | 4 | IPFS hashes are permanent, content-addressed identifiers for your content. This means that you can use many different ways to access, replicate, and/or redistribute the same content using the same link/identifier. The lessons in this tutorial explore many of the ways that you can do this. If you want to learn about why it is valuable to have all of these options, read the lesson on [the power of content-addressing](/avenues-for-access/lessons/power-of-content-addressing.md) 5 | 6 | (based on https://en.wikipedia.org/wiki/Content_addressable_network) 7 | 8 | All of the lessons use the same content: a snapshot of the Turkish version of Wikipedia. 9 | 10 | ## Learning Objectives 11 | These Lessons will teach you how to 12 | * Define _content addressing_ and compare it with _location-addressing_ 13 | * Use IPFS content hashes to access the same content in many ways with the same link 14 | * Access content through the public IPFS gateways at ipfs.io 15 | * Access content through any IPFS node's http gateway 16 | * Access content using the IPFS browser extension 17 | * Access IPFS content through Tor 18 | * Use a sneakernet to move and redistribute IPFS content 19 | * Explain the implications of being able to access IPFS content through so many different paths 20 | 21 | ## Lessons 22 | 23 | 1. Read about [The Power of Content-addressing](/avenues-for-access/lessons/power-of-content-addressing.md) 24 | 2. Review the lesson on [Retrieving content from a peer](/going-online/lessons/retrieve-from-peer.md) 25 | 3. Review these lessons from the Tutorial on Interacting with the Classical (HTTP) Web 26 | - Review: [Lesson: Using an HTTP browser to retrieve files from local IPFS gateway](/classical-web/lessons/local-gateway.md) 27 | - Review: [Lesson: Using the public IPFS gateways at ipfs.io](/classical-web/lessons/public-gateways.md) 28 | - Review: [Lesson: Access IPFS content through any IPFS gateway](/classical-web/lessons/other-gateways.md) 29 | 4. [Lesson: Access IPFS content through Tor gateways (experimental)](/avenues-for-access/lessons/tor-gateways.md) 30 | 5. [Lesson: Run IPFS over Tor transport (experimental)](/avenues-for-access/lessons/tor-transport.md) 31 | 6. [Lesson: Access IPFS content through a browser extension](/avenues-for-access/lessons/browser-extension.md) 32 | 7. [Lesson: Sneakernets - moving the data on USB Drives and other Hardware](/avenues-for-access/lessons/sneakernets.md) 33 | 34 | 35 | ## Next Steps 36 | 37 | If you're wondering how to update content after you've shared it, see the [Tutorial: Publishing Changes on the Permanent Web](/publishing-changes/README.md) 38 | 39 | If you want to know more about how IPFS stores this content intrernally using Merkle DAGs, go to the [Tutorial: Merkle Trees and the IPFS DAG](/ipfs-dag/README.md) 40 | -------------------------------------------------------------------------------- /avenues-for-access/lessons/browser-extension.md: -------------------------------------------------------------------------------- 1 | # Lesson: Access IPFS content through a browser extension 2 | 3 | _This is a placeholder. There are currently four web browser extensions that help your retrieve content from IPFS. Each works in slightly different ways. We are in the process of consolidating that code and making it more secure before we encourage people to rely on it._ 4 | 5 | When the IPFS browser extension is complete, we will publish it on the app stores for all of the browsers that support it. When you download the extension, it will automatically recognize IPFS links and will use the IPFS peer-to-peer network to retrieve the content for you -- no HTTP gateway needed, nothing else to install on your computer, no need to use the command line. You will only have to install the browser extension and the whole IPFS network will become available to you. 6 | 7 | We consider this the next big step to getting IPFS natively supported in web browsers. You can track this work in the github repository at https://github.com/ipfs/in-web-browsers. [This comment on a github issue](https://github.com/ipfs/pm/issues/351#issuecomment-294262546) describes the state of these efforts as of April 2017. 8 | 9 | Among other things, this support for IPFS in browsers will make it possible to start using links that are truly content-addressed, without any reference to HTTP locations, even when you access content through a web browser. We are advocating for this to be done using a new `dweb:` address scheme. Using the `dweb:` scheme, the links to the wikipedia page we're using as an example in all of the lessons in the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) will look like this: 10 | 11 | - 2017-04-30 snapshot: dweb:/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 12 | - latest (IPNS): dweb:/ipns/QmQP99yW82xNKPxXLroxj1rMYMGF6Grwjj2o4svsdmGh7S/wiki/Anasayfa.html 13 | - latest (DNS): dweb:/ipns/wikipedia-on-ipfs.io 14 | 15 | ## Next Steps 16 | 17 | Return to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link. 18 | -------------------------------------------------------------------------------- /avenues-for-access/lessons/power-of-content-addressing.md: -------------------------------------------------------------------------------- 1 | # Lesson: The Power of Content-addressing 2 | 3 | ## Goals 4 | 5 | This lesson introduces the concept of _content addressing_ and explores the powerful implications of using this approach. 6 | 7 | After doing this Lesson you will be able to 8 | * Define _content addressing_ and compare it with _location-addressing_ 9 | * Explain the implications of being able to access IPFS content through so many different paths 10 | 11 | ## Explanation 12 | 13 | ### The Problem: Identifying Content by its Location 14 | 15 | When you use an `http://` or `https://` link to point to a webpage, image, spreadsheet, dataset, tweet, etc, you're identifying content by its location. The link is an identifier that points to a particular location on the web, which corresponds to a particular server, or set of servers, somewhere on the web. **Whoever controls that location controls the content.** That's how HTTP works. It's _location-addressed_. Even if a thousand people have downloaded copies of a file, meaning that the content exists in a thousand locations, HTTP points to a single location. This location-addressed approach forces us all to pretend that the data are in only one location. Whoever controls that location decides what content to return when people use that link. They also decide whether to return any content at all. 16 | 17 | To get a sense of how impractical it is to address content by its location, imagine if I used location-addressing to recommend the book [Why Information Grows](http://www.goodreads.com/book/show/20763722-why-information-grows). 18 | 19 | If I identify the book by its content, saying "Check out the book called _Why Information Grows_ by César Hidalgo. The ISBN is 0465048994.", you will be able to get any copy of the book from any source and know that you're reading the information I recommended. You might even say "Oh. I already read it." or "My roommate has it in the other room. I'll borrow it from him.", saving yourself the cost or effort of getting another copy. 20 | 21 | By contrast, if I used location-addressing to identify the book, I would have to point to a location, saying something like "Go to the news stand at Market & 15th in Philadelphia and ask for the thing 16 inches from the south end of the third shelf on the east wall" Those instructions are confusing and awkward, but that is how http links work. They identify content by its location and they rely on the 'host' at that location to provide the content to visitors. There are lots of things that could go wrong with this approach. It also puts a lot of power and responsibility on the shoulders of whoever controls the location you're pointing to - in this case the news stand. 22 | 23 | Let's consider the responsibilities of whoever controls the location we've pointed to. If the people running the news stand want my directions (aka. my "link") to remain valid, allowing people to access the book, they have to: 24 | 25 | * Always be open, 24/7, in case someone wants to read the book. 26 | * Provide the book to _everyone_ who seeks the book, whether it's one person or hundreds of thousands of people. 27 | * Protect the integrity of the book by preventing anyone from tampering with it. 28 | * Never remove the book from its shelf - if they get rid of it, or even move it, my link is broken and nobody will be able to use my instructions to find the book. 29 | 30 | Along with those responsibilities come a great amount of power. The proprietors of the news stand control the location that my directions point to, so they can choose to: 31 | 32 | * Dictate who is allowed to see the book. 33 | * Move the book without telling anyone. 34 | * Destroy the book. 35 | * Charge people money to access the book or force them to watch ads when they walk in the door. 36 | * Collect data about everyone who accesses my book, using that information however they want. 37 | * Replace the book with something else -- They might not even put a book there, since my instructions are just describing a location, a malicious actor could replace the book with something dangerous, turning the location into a trap! 38 | 39 | Location-addressing has worked on the web for 25 years, but it's starting to get painful and It's about to get much worse. As long as we continue to rely on it, the web will continue to be unstable, insecure, and prone to manipulation or exploitation. 40 | 41 | ### The Solution: Identify Information by its Fingerprint, not its Location 42 | 43 | The alternative is to identify content by its "fingerprint" rather than identifying it by its location. That way, when someone says "Look at the content with this fingerprint" you can get it from anyone who has a copy of the content. To do this, we identify content by its cryptographic hash. A cryptographic hash is a short string of letters and numbers that's calculated by feeding your content into a _cryptographic hash function_ like [SHA](https://en.wikipedia.org/wiki/SHA-3). 44 | 45 | When we identify content in this way, using the content's cryptographic hash instead of its location to identify it, this is called _content-addressing_. 46 | The cryptographic hash for a piece of content never changes, which means **content addressing guarantees that the links will always return the same content**, regardless of _where_ I retrieve the content from, regardless of _who_ added the content to the network, and regardless of when the content was added. That's the essential power of using a _content-addressed_ protocol like IPFS instead of using a _location-addressed_ protocol like HTTP. 47 | 48 | ### The Implications of Content Addressing 49 | 50 | **Content-addressed links are permanent.** The link permanently points to _exactly_ that content. This has many powerful implications. From a computer science perspective, any time we create data that uses content-addressed links, we are creating a [persistent data structure](https://en.wikipedia.org/wiki/Persistent_data_structure). There is a great amount of literature on the applications for persistent data structures. For this lesson, we will call out just a few implications of _storing_ and _sharing_ data using a content-addressed protocol: 51 | 52 | #### It lets us store data together. 53 | 54 | This decentralized, content-addressed approach radically increases the durability of data. It ensures that data will not become endangered as long as anyone is still relying on it because anyone can hold a valid copy of the data they care about. If you hold a copy of a dataset on any of your devices, or if you pay someone to host it on an IPFS node for you, you become part of the network of stewards who protect that dataset from being lost. You won't have to worry about whether someone is going to turn off the servers where your data are hosted because _you are one of the hosts_. You and your peers hold the data among yourselves and are able to share the data directly with each other without relying on centralized points of failure. 55 | 56 | #### It increases the integrity of data. 57 | 58 | Decentralization also increases the integrity of data because links are content-addressed. This means we can validate data by checking the data's fingerprints against the links. That kind of validation is impossible with location-addressed links. This is especially powerful on the large scale, where millions of websites and datasets reference each other billions of times. With location-addressed links, all of those connections are brittle. With content-addressed links, the connections become resilient and reliable. 59 | 60 | #### Links can come back to life. 61 | 62 | **As soon as any node has the content, everyone's links start working.** Even if someone destroys all the copies on the network, it only takes one node adding the content in order to restore availability. A cryptographic hash _permanently_ points to the content it was derived from, so IPFS links permanently point to their content. Even if the content becomes unavailable for a period, the links will work as soon as anyone starts providing the content again. 63 | 64 | #### Harder to attack, easier to recover. 65 | 66 | **Even if the original publisher is taken down, the content can be served by anyone who has it.** As long as at least one node on the network has a copy of the content, everyone will be able to get it. This means the responsibility for serving content can change over time without changing the way people link to the content and without any doubt that the content you're reading is exactly the content that was originally published. 67 | 68 | **The content you download is cryptographically verified** to ensure that it hasn’t been tampered with. 69 | 70 | **IPFS can work in partitioned networks** - you don’t need a stable connection to the rest of the web in order to access content through IPFS. As long as your node can connect to at least one node with the content you want, it works! 71 | 72 | **If one IPFS gateway gets blocked, you can use another one.** IPFS gateways are all capable of serving the same content, so you’re not stuck relying on one point of failure. 73 | 74 | **Lightening the load**: With IPFS, people viewing the content are also helping distribute the content (unless they opt out) and anyone can choose to pin a copy of some content on their node in order to help with access and preservation. 75 | 76 | **You can read anonymously.** As with HTTP, IPFS can work over Tor and other anonymity systems 77 | 78 | **IPFS does not rely on DNS**. If someone blocks your access to DNS or spoofs DNS in your network, it will not prevent IPFS nodes from resolving content over the peer-to-peer network. Even if you're using the DNSlink feature of IPFS, you just need to find a gateway that _does_ have access to DNS. As long as the gateway you're relying on has access to DNS it will be able to resolve your DNSlink addresses. 79 | 80 | **IPFS does not rely on the Certificate Authority System**, so bad or corrupt Certificate Authorities do not impact it. 81 | 82 | **You can move content via [sneakernet](https://en.wikipedia.org/wiki/Sneakernet)!** _This is very useful in areas with poor connectivity, due to resource limitations, security reasons, or censorship._ Even if your network is physically disconnected from the rest of the internet, you can write content from IPFS onto USB drives or other external drives, physically move them to computers connected to a new network, and re-publish the content on the new network. Even though you're on a separate network, IPFS will let nodes access the content using the same identifiers in both networks as long as at least one node on the network has that content. 83 | 84 | **IPFS nodes work hard to find each other on the network** and to reconnect with each other after connections get cut. 85 | 86 | (experimental) **You can even form private IPFS networks** to share information _only_ with computers you've chosen to connect with. 87 | 88 | ## Further Reading 89 | 90 | Further light Reading: 91 | - [HTTP is obsolete. It's time for the distributed, permanent web](https://ipfs.io/ipfs/QmNhFJjGcMPqpuYfxL62VVB9528NXqDNMFXiqN5bgFYiZ1/its-time-for-the-permanent-web.html) 92 | - [Instructions for Saving Endangered Data](https://github.com/ipfs/community/blob/master/articles/endangered-data.md) 93 | 94 | Videos to Watch: 95 | - [this part of a talk by Juan Benet talk](https://youtu.be/2RCwZDRwk48?t=847) 96 | 97 | Academic Papers: 98 | - [The IPFS Whitepaper](https://github.com/ipfs/papers/raw/master/ipfs-cap2pfs/ipfs-p2p-file-system.pdf) 99 | 100 | ## Next Steps 101 | 102 | Read the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) to learn about the many different ways you can use IPFS to access the same content using the same content-addressed link. 103 | -------------------------------------------------------------------------------- /avenues-for-access/lessons/sneakernets.md: -------------------------------------------------------------------------------- 1 | # Lesson: Sneakernets - moving the data on USB Drives and other Hardware 2 | 3 | We're not kidding. If you'd like to move IPFS content between networks via [sneakernet](https://en.wikipedia.org/wiki/Sneakernet), IPFS is just fine with that. This lesson covers how to load IPFS content onto storage devices like USB drives so that you can physically move the content to new networks and then re-publish it. Without ever relying on a direct connection between the networks, this will make the IPFS links for your content valid on both sides of the air gap. 4 | 5 | Examples of how this is useful: 6 | * Make internet content available in places that don't have direct connections to the internet backbone (remote locations with limited connectivity, space stations) 7 | * Circumvent censorship by governments, corporations and overbearing parents. 8 | 9 | For this example we will pretend you're using an external drive to move a snapshot of wikipedia from IPFS to a new network where wikipedia isn't available. 10 | 11 | ## Prerequisites 12 | To do the steps in this lesson you must: 13 | * Be familiar with using the command line 14 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 15 | 16 | ## Goals 17 | 18 | After doing this Lesson you will know how to physically move IPFS content across an airgap, making it available over IPFS and HTTP on the other side. 19 | 20 | ## Steps 21 | 22 | ### Step 1: Download the content you want to move, plus a copy of IPFS 23 | 24 | Use `ipfs get` command to download the content you want to move across networks. In this example, we download a complete snapshot of Wikipedia archive to disk, saving it as a folder called `WikipediaSnapshot` _(Warning: this snapshot is 15 GB. You might want to use something smaller)_: 25 | 26 | ```sh 27 | $ ipfs get Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html -o WikipediaSnapshot 28 | ``` 29 | 30 | Download the latest IPFS binaries into your drive too. You will need this in order to publish the content on the other side. Make sure to download the appropriate go-ipfs binary for the computer you will be moving the data to. *Note: there might be a newer version of ipfs available when you read this. Find out the most current version number at https://dist.ipfs.io/#go-ipfs* 31 | 32 | ```sh 33 | $ ipfs get /ipns/dist.ipfs.io/go-ipfs/v0.4.8 -o go-ipfs-v0.4.8 34 | ``` 35 | 36 | ### Step 2: Copy the files to your external drive 37 | 38 | - Copy the snapshot (ie. the folder "WikipediaSnapshot") to your external drive 39 | - Copy the IPFS binaries you downloaded (ie. the folder "go-ipfs-v0.4.8") into your external drive 40 | 41 | ### Step 3: Move to the next computer 42 | 43 | - Eject your external drive 44 | - Physically carry your external drive to the next computer you want to use the information from. 45 | 46 | ### Step 4: Install IPFS on the next computer and load the content 47 | 48 | First Install and initialize the IPFS binary on the new computer. The instructions in [the installation tutorial](/install-ipfs/README.md) might help. 49 | 50 | Then import the data into ipfs (in this case, the folder called `WikipediaSnapshot`) 51 | 52 | ```sh 53 | $ ipfs add -r WikipediaSnapshot 54 | ``` 55 | 56 | ### Step 5: Confirm that the content is now available on the new computer 57 | 58 | Start the ipfs daemon: 59 | 60 | ```sh 61 | ipfs daemon 62 | ``` 63 | 64 | The snapshot link should now work: http://localhost:8080/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 65 | 66 | ## Explanation 67 | 68 | This approach allows you to physically move IPFS content into networks where it was previously unavailable. 69 | 70 | Because IPFS uses content-addressing, as long as the content you added to the second network is identical to the original content you originally exported from IPFS, the IPFS identifier for your content will be identical in both networks. 71 | 72 | ## Next Steps 73 | 74 | Return to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link. 75 | 76 | Next, proceed to the [Making Changes on the Permanent Web](../../publishing-changes/README.md) tutorial. 77 | -------------------------------------------------------------------------------- /avenues-for-access/lessons/tor-gateways.md: -------------------------------------------------------------------------------- 1 | # Lesson: Access IPFS through Tor gateways (experimental) 2 | 3 | ## Goals 4 | 5 | This lesson covers accessing IPFS content through Tor gateways. 6 | 7 | After doing this Lesson you will be able to 8 | * Use the Tor browser and a public IPFS gateway on the Tor network to access IPFS content 9 | 10 | ## Steps 11 | 12 | ### Step 1: Download the Tor browser 13 | 14 | If you do not already have the Tor browser installed, download the Tor browser from the Tor project by visiting https://www.torproject.org/projects/torbrowser.html.en 15 | 16 | In some countries the Tor Project website is blocked or censored and it is not possible to download Tor directly. The Tor Project also hosts a mirror of [Tor Browser Bundle on Github](https://github.com/TheTorProject/gettorbrowser). 17 | 18 | The [GetTor](https://www.torproject.org/projects/gettor) service can also be used to download Tor Browser when the Project website and mirrors are blocked. 19 | 20 | ### Step 2: Request the content you want from the IPFS-Tor gateway 21 | 22 | `ipfs4uvgthshqonk.onion` is a volunteer-run IPFS Gateway on the Tor network. You will use this gateway to request IPFS content. 23 | _(Warning: The IPFS project does not run this gateway. We cannot guarantee stability or security.)_ There are probably many other IPFS gateways on the Tor network. You can use any of them in this way -- simply replace `ipfs4uvgthshqonk.onion` with the name of the gateway you're trying to access. 24 | 25 | With the Tor browser running, enter the hash of the IPFS content you want to retrieve. This part is the same as [using any other IPFS gateway](../../classical-web/lessons/other-gateways.md) -- only the address of the gateway is different: If you're using the hash of a specific snapshot of content, use the path `https://ipfs4uvgthshqonk.onion/ipfs/`. If you're using an IPNS hash to get the _latest_ version of some content, use the path `https://ipfs4uvgthshqonk.onion/ipns/` 26 | 27 | To view the wikipedia page we're using as an example in all of the lessons in the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md), use these links: 28 | 29 | - 2017-04-30 snapshot: https://ipfs4uvgthshqonk.onion/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 30 | - latest (IPNS): https://ipfs4uvgthshqonk.onion/ipns/QmQP99yW82xNKPxXLroxj1rMYMGF6Grwjj2o4svsdmGh7S/wiki/Anasayfa.html 31 | - latest (DNS): https://ipfs4uvgthshqonk.onion/ipns/wikipedia-on-ipfs.io 32 | 33 | - (you can verify it works with [onion.link](https://onion.link)) 34 | 35 | ## Explanation 36 | 37 | This approach relies on the IPFS gateway at `ipfs4uvgthshqonk.onion` to retrieve content from the IPFS network for you. The difference with this gateway, as opposed to the gateways at ipfs.io, is that it's listening for requests directly over Tor protocol. This allows you to access the gateway anonymously. 38 | 39 | ## Next Steps 40 | 41 | Read about how you can [configure an IPFS node to use the Tor transport](/avenues-for-access/lessons/tor-transport.md) or return to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link. 42 | -------------------------------------------------------------------------------- /avenues-for-access/lessons/tor-transport.md: -------------------------------------------------------------------------------- 1 | # Lesson: Run IPFS over Tor transport (experimental) 2 | 3 | IPFS has an experimental feature that allows an IPFS node to interact with other IPFS nodes over the Tor transport protocol. The goal of this feature is to allow IPFS nodes to anonymously communicate with each other. **This feature is experimental!** Until we have tested this feature and removed the "experimental" designation, you should assume that information about your node might leak. 4 | 5 | In the meantime, a more secure way to protect your anonymity would be to [access data using the tor browser and an IPFS tor gateway](/avenues-for-access/lessons/tor-gateways.md). 6 | 7 | ## Prerequisites 8 | 9 | To do the steps in this lesson you must: 10 | * Be familiar with using the command line 11 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 12 | 13 | ## Goals 14 | 15 | After doing this Lesson you will be able to 16 | * Configure an IPFS node to use the Tor transport 17 | * Request content through that node 18 | 19 | ## Steps 20 | 21 | ### Step 1: Configure IPFS to use the Tor transport 22 | 23 | Work-In-Progress: https://github.com/ipfs/notes/issues/37 24 | 25 | Work-In-Progress: https://github.com/OpenBazaar/go-onion-transport 26 | 27 | TODO - *This explanation has not been written yet. If you want to help work on it, or if you want to encourage us to give it attention, open an issue at https://github.com/ipfs-shipyard/ipfs-primer/issues* 28 | 29 | ### Step 2: Start the IPFS daemon 30 | 31 | Start the IPFS daemon 32 | 33 | ```sh 34 | $ ipfs daemon 35 | ``` 36 | 37 | For more info about this step, read [Tutorial: Going Online - Joining the Distributed Web](/going-online/README.md) 38 | 39 | ### Step 3: Request the content you want from your local IPFS node's gateway 40 | 41 | This step is the same as [using any other IPFS gateway](../../classical-web/lessons/other-gateways.md) -- only the address of the gateway is different: If you're using the hash of a specific snapshot of content, use the path `http://localhost:8080/ipfs/`. If you're using an IPNS hash to get the _latest_ version of some content, use the path `http://localhost:8080/ipns/` 42 | 43 | To view the wikipedia page we're using as an example in all of the lessons in the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md), use these links: 44 | 45 | - 2017-04-30 snapshot: http://localhost:8080/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 46 | - latest (IPNS): http://localhost:8080/ipns/QmQP99yW82xNKPxXLroxj1rMYMGF6Grwjj2o4svsdmGh7S/wiki/Anasayfa.html 47 | - latest (DNS): http://localhost:8080/ipns/wikipedia-on-ipfs.io 48 | 49 | ## Explanation 50 | 51 | **This feature is experimental!** Until we have tested this feature and removed the "experimental" designation, you should assume that the explanation here is aspirational and provisional. We are describing what _should_ be true but we have not yet tested and confirmed that the approach works without leaking information. 52 | 53 | When you configure an IPFS node to use the Tor transport, the node will pipe all of its peer-to-peer communications through the Tor onion network. This means that when you request content from your local node, whether through its http gateway at localhost:8080 or through the command line, the node will access the IPFS network over the tor transport protocol. When it connects with peer nodes on the IPFS network, the peers will not know which node they are talking to nor where it is. 54 | 55 | ## Next Steps 56 | 57 | Return to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md) to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link. 58 | -------------------------------------------------------------------------------- /build-book.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "building html" 4 | gitbook build 5 | echo "building pdf" 6 | gitbook pdf ./ _book/ipfs-primer.pdf 7 | echo "building epub" 8 | gitbook epub ./ _book/ipfs-primer.epub 9 | echo "building mobi" 10 | gitbook mobi ./ _book/ipfs-primer.mobi 11 | 12 | echo "...done. Everything is in _book/" 13 | -------------------------------------------------------------------------------- /classical-web/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Interacting with the Classical (HTTP) Web 2 | 3 | ## Prerequisites 4 | 5 | To do the lessons in this tutorial you must: 6 | * Be familiar with using the command line 7 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 8 | * [Take your IPFS Node Online](/going-online/README.md) 9 | 10 | ## Learning Objectives 11 | These Lessons will teach you how to 12 | * Use your browser to retrieve content through different IPFS gateways 13 | 14 | ## Key Concepts 15 | * Flexibly downloading content from the IPFS network 16 | 17 | ## Lessons 18 | 19 | 1. [Lesson: Use an HTTP browser to retrieve files from local IPFS gateway](/classical-web/lessons/local-gateway.md) 20 | 2. [Lesson: Get content through the public ipfs.io gateway](/classical-web/lessons/public-gateways.md) 21 | 3. [Lesson: Access IPFS content through any IPFS gateway](/classical-web/lessons/other-gateways.md) 22 | -------------------------------------------------------------------------------- /classical-web/lessons/local-gateway.md: -------------------------------------------------------------------------------- 1 | # Lesson: Using an HTTP browser to retrieve files from a local IPFS gateway 2 | 3 | This lesson shows some of the different ways to access content through an IPFS node that you have installed locally on your computer. Some of the underlying topics are covered in greater depth in the tutorials about [Files on IPFS](/files-on-ipfs/README.md) and [Going Online - Joining the Distributed Web](/going-online/README.md). 4 | 5 | ## Prerequisites 6 | To do the steps in this lesson you must: 7 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 8 | 9 | ## Goals 10 | 11 | After doing this Lesson you will be able to 12 | * Access any content through your local IPFS node's HTTP gateway 13 | 14 | ## Steps 15 | 16 | ### Step 1: Start the IPFS daemon 17 | 18 | Start the IPFS daemon by running 19 | 20 | ```sh 21 | $ ipfs daemon 22 | ``` 23 | 24 | If the daemon is not running, your IPFS node won't be able to retrieve content from other nodes on the network. It also won't start the HTTP gateway that you're going to use in Step 2. 25 | 26 | ### Step 2: Read request content through your IPFS node's HTTP gateway 27 | 28 | You must tell the gateway whether you're requesting content with an IPFS hash or an IPNS hash. If you're using the hash of a specific snapshot of content -- for example a file that someone added to IPFS, use a path that starts with `/ipfs/`. If you're using an IPNS hash to get the _latest_ version of some content that gets updated over time, for example a website that gets fresh content every day, use a path that starts with `/ipns/`. 29 | 30 | To view the wikipedia page we're using as an example in all of the lessons in the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md), use these links: 31 | 32 | - 2017-04-30 snapshot: http://localhost:8080/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 33 | - latest (IPNS): http://localhost:8080/ipns/QmQP99yW82xNKPxXLroxj1rMYMGF6Grwjj2o4svsdmGh7S/wiki/Anasayfa.html [correct example though this link may be stale] 34 | - latest (DNS): http://localhost:8080/ipns/ipfs.io 35 | 36 | ## Explanation 37 | 38 | You can use a local IPFS node to read content from the worldwide IPFS network. The two ways of interacting with your local node are 1) through the command line and 2) through the HTTP gateway. You can use either of those interfaces to pass IPFS the content-addressed (hash) identifiers of the content you want. The IPFS node will use those identifiers to find that content on the network and retrieve it for you. 39 | 40 | ## Next Steps 41 | 42 | If you want to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link, go to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md). 43 | 44 | Otherwise proceed to the next lesson to learn how to [Get content through the public ipfs.io gateway](/classical-web/lessons/public-gateways.md) 45 | -------------------------------------------------------------------------------- /classical-web/lessons/other-gateways.md: -------------------------------------------------------------------------------- 1 | # Lesson: Access IPFS content through any IPFS gateway 2 | 3 | ## Goals 4 | 5 | This lesson covers using _any_ IPFS gateway to access IPFS content. It's a condensed review of the [Lesson on Using an HTTP browser to retrieve files from a local IPFS gateway](/classical-web/lessons/local-gateway.md) 6 | 7 | After doing this Lesson you will be able to 8 | * Use the HTTP address of any IPFS gateway to access IPFS content 9 | 10 | ## Steps 11 | 12 | ### Step 1: Get the address of a gateway 13 | 14 | As we covered in [Tutorial: Going Online - Joining the Distributed Web](/going-online/README.md), when you run an IPFS daemon, it exposes an HTTP endpoint that acts as a gateway between HTTP and the IPFS network. This means that you can, in theory, point your web browser at any IPFS node's HTTP endpoint and use it as a gateway. In reality, the person operating that node usually needs to take extra steps to make their gateway available over HTTP (NAT traversal, etc). 15 | 16 | For these examples we will use the gateway at `http://dweb.link` 17 | 18 | ### Step 2: Build the Path to your Content 19 | 20 | As described in the [Lesson on Using an HTTP browser to retrieve files from local IPFS gateway](/classical-web/lessons/local-gateway.md), you must tell the gateway whether you're requesting content with an IPFS hash or an IPNS hash. If you're using the hash of a specific snapshot of content -- for example a file that someone added to IPFS, use the path `/ipfs/`. If you're using an IPNS hash to get the _latest_ version of some content that gets updated over time, for example a website that gets fresh content every day, use the path `/ipns/` 21 | 22 | 23 | ### Step 3: Request the content from the gateway 24 | Combine the gateway's address (ie. `http://dweb.link`) with the path to your content (ie. `/ipfs/`). Use that to request the content. 25 | 26 | To view the wikipedia page we're using as an example in all of the lessons in the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md), use these links: 27 | 28 | - 2017-04-30 snapshot: http://dweb.link/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 29 | - latest (IPNS): http://dweb.link/ipns/QmQP99yW82xNKPxXLroxj1rMYMGF6Grwjj2o4svsdmGh7S/wiki/Anasayfa.html [correct example though this link may be stale] 30 | - latest (DNS): http://dweb.link/ipns/ipfs.io 31 | 32 | ## Explanation 33 | With the above examples, we are using an HTTP connection over the internet to someone (`http://dweb.link`) providing a gateway onto the IPFS network. In this way you can access information in the IPFS network at large, and you do not need to run your own IPFS gateway. 34 | 35 | TODO 36 | * Restricting the content that your gateway will serve 37 | * Security concerns -- the gateway can see all the things that an HTTP server can see. 38 | 39 | ## Next Steps 40 | 41 | If you want to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link, go to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md). 42 | 43 | Otherwise return to the tutorial on [Interacting with the Classical (HTTP) web](/classical-web/README.md) 44 | -------------------------------------------------------------------------------- /classical-web/lessons/public-gateways.md: -------------------------------------------------------------------------------- 1 | # Lesson: Using the public IPFS gateways at ipfs.io to access content 2 | 3 | This lesson explains how to retrieve IPFS content from the public IPFS gateways at ipfs.io. This topic is covered in greater depth in the tutorial on [Interacting with the Classical (HTTP) Web](/classical-web/README.md). 4 | 5 | ## Goals 6 | 7 | After doing this Lesson you will be able to 8 | * Use the public gateway at ipfs.io to access IPFS content 9 | 10 | ## How to Do It 11 | 12 | This process is the same as [using any other IPFS gateway](/classical-web/lessons/other-gateways.md) -- only the address of the gateway is different: If you're using the hash of a specific snapshot of content, use the path `https://ipfs.io/ipfs/`. If you're using an IPNS hash to get the _latest_ version of some content, use the path `https://ipfs.io/ipns/` 13 | 14 | To view the wikipedia page we're using as an example in all of the lessons in the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md), use these links: 15 | 16 | - 2017-04-30 snapshot: http://ipfs.io/ipfs/Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Anasayfa.html 17 | - latest (IPNS): http://ipfs.io/ipns/QmQP99yW82xNKPxXLroxj1rMYMGF6Grwjj2o4svsdmGh7S/wiki/Anasayfa.html [correct example though this link may be stale] 18 | - latest (DNS): http://ipfs.io/ipns/ipfs.io 19 | 20 | ## Explanation 21 | 22 | The IPFS project maintains public IPFS gateways that you can use to access any content from the IPFS network. When sharing HTTP links to IPFS content, people often use ipfs.io addresses but you can use the address of any gateway. 23 | 24 | ## Next Steps 25 | 26 | If you want to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link, go to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](/avenues-for-access/README.md). 27 | 28 | Otherwise proceed to the next lesson to learn how to [Access IPFS content through any IPFS gateway](/classical-web/lessons/other-gateways.md) 29 | -------------------------------------------------------------------------------- /dynamic-content/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Dynamic Content on IPFS 2 | 3 | ## Concepts 4 | These Lessons introduce the following concepts: 5 | * Immutability: "Changes" as _additions_ to the tree 6 | * CRDTs 7 | * Pubsub 8 | * Authenticated Streams (with pubsub) 9 | 10 | ## Prerequisites 11 | 12 | ## Lessons 13 | 14 | 1. Disclaimer: Dynamic content on IPFS is a Work in Progress 15 | 2. Lesson: Add data to the DAG (locally) 16 | 3. Lesson: Tell peers about your Changes 17 | 4. Lesson: Use hashes to get someone's changes from IPFS 18 | 5. Lesson: Use a pub/sub strategy to pass around messages about changes 19 | 6. Lesson: Resolve conflicts with a merge strategy (CRDTs) 20 | -------------------------------------------------------------------------------- /files-on-ipfs/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Files on IPFS 2 | These Lessons are tested with go-ipfs versions: 3 | 0.5.0, 4 | 0.9.0 5 | 6 | _Please update this file on github to reflect any other versions that have been tested._ 7 | 8 | ## Prerequisites 9 | 10 | - You should have some familiarity with the command line. 11 | - You should have `ipfs` installed - the [previous tutorial](../install-ipfs) has instructions for that 12 | 13 | ## Learning Objectives 14 | These Lessons will teach you how to 15 | * Add files to your local IPFS node 16 | * Read files out of your local IPFS node 17 | * List the files in your IPFS node 18 | * Tell IPFS to hold onto files by _pinning_ them 19 | 20 | ## Key Concepts 21 | * Distinction between IPFS and your regular Filesystem 22 | * Identifying files by their Hashes 23 | * IPFS Garbage Collection 24 | * Pinning files on an IPFS Node 25 | 26 | ## Lessons 27 | 28 | 1. [Lesson: Add Content to IPFS and Retrieve It](/files-on-ipfs/lessons/add-and-retrieve-file-content.md) 29 | 2. [Lesson: Wrap Filenames and Directory Info around Content in IPFS](/files-on-ipfs/lessons/wrap-directories-around-content.md) 30 | 3. [Lesson: Pinning - Tell IPFS to Keep a File](/files-on-ipfs/lessons/pin-files.md) 31 | 32 | ## Next Steps 33 | 34 | Once you know how to add files to IPFS and retrieve them, you will be ready to share those files on the P2P network following the [Tutorial: Going Online - Joining the Distributed Web](/going-online/README.md) 35 | 36 | If you're wondering how to update those files after you've shared them, see the [Tutorial: Publishing Changes on the Permanent Web](/publishing-changes/README.md) 37 | 38 | If you want to see how to access those files from the conventional HTTP web, go to the [Tutorial: Interacting with the Classical (HTTP) Web](/classical-web/README.md) 39 | 40 | If you want to know more about how IPFS stores this content internally using Merkle DAGs, go to the [Tutorial: Merkle Trees and the IPFS DAG](/ipfs-dag/README.md) 41 | -------------------------------------------------------------------------------- /files-on-ipfs/lessons/add-and-retrieve-file-content.md: -------------------------------------------------------------------------------- 1 | # Lesson: Add Content to IPFS and Retrieve It 2 | 3 | ## Goals 4 | After doing this Lesson you will be able to 5 | * Add a file's content to IPFS 6 | * Read content out of IPFS using its hash 7 | * Explain the relationship between IPFS hashes and the content you've added 8 | 9 | ## Steps 10 | 11 | ### Step 1: Create a file that you will add to IPFS 12 | 13 |
14 | You can add any type of content to IPFS. For this lesson we will put some text content into a `.txt` file, but you can do this same process with any content or any file. 15 |
16 | 17 | It would be a good idea to make a new directory for this example. Navigate to somewhere you are comfortable putting a new folder (such as `~/Desktop`), and then create a new directory and go into it. Here is an example command: 18 | 19 | ```sh 20 | $ cd ~/Desktop 21 | $ mkdir ipfs-tutorial 22 | $ cd ipfs-tutorial 23 | ``` 24 | 25 | Now, create a file called `mytextfile.txt` and put the text "version 1 of my text" in it. One easy way to do this on the command line is with this command: 26 | 27 | ```sh 28 | $ echo "version 1 of my text" > mytextfile.txt 29 | ``` 30 | 31 | You can read the file's contents using the `cat` command: 32 | 33 | ```sh 34 | $ cat mytextfile.txt 35 | version 1 of my text 36 | ``` 37 | 38 | ### Step 2: Add the File to IPFS 39 | 40 | ```sh 41 | $ ipfs add mytextfile.txt 42 | added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy mytextfile.txt 43 | ``` 44 | 45 | Save the hash `QmZtmD2qt...` that ipfs returned. This is the content's cryptographic hash. If the file's content changes, the hash will change, but if the file's content remains the same, the hash will always be the same. 46 | 47 | Bear in mind that if you're not [running the daemon](/going-online/lessons/connect-your-node.md#step-1-start-the-ipfs-daemon), it will just add locally. If you start the daemon later, the blocks will be advertised after a few seconds when the reprovider runs. 48 | 49 | ### Step 3: Read the content out of IPFS 50 | 51 | Just like the regular `cat` command lets you read the contents of a file, the `ipfs cat` command lets you read the contents of a file that has been added to ipfs. 52 | 53 | Use the `ipfs cat` command to read the content by passing it the content's cryptographic hash -- this is the hash that ipfs returned when you ran `ipfs add mytextfile.txt`. 54 | 55 | ```sh 56 | $ ipfs cat QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy 57 | version 1 of my text 58 | 59 | ``` 60 | 61 | Notice that this returned the _content_ of the file, not the text file itself. That's because `QmZtmD2qt...` is the hash of the content, not the file itself. We'll test that in the next step. 62 | 63 | ### Step 4: Confirm that the hash points to the content, not the file 64 | 65 | When you used `ipfs cat` to read the file's contents it returned the _content_ of the file, not the text file itself. That's because the hash `QmZtmD2qt...` is the hash of the _content_. You can test that by adding the text content directly to IPFS without ever putting it in a file. 66 | 67 | 68 | ```sh 69 | $ echo "version 1 of my text" | ipfs add 70 | added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy 71 | ``` 72 | 73 | The hash should be exactly the same as the hash you got when you added mytextfile.txt. If you want to triple-check, you can run each of these commands as many times as you want. The hash should always be the same. 74 | 75 | ```sh 76 | $ ipfs add mytextfile.txt 77 | added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy mytextfile.txt 78 | $ echo "version 1 of my text" | ipfs add 79 | added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy 80 | $ cat mytextfile.txt | ipfs add 81 | added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy 82 | ``` 83 | 84 | As long as the content remains the same, you will always get the same hash. As far as IPFS is concerned, it _is_ the same content. 85 | 86 | ### Step 5: Change the content and get a different hash 87 | 88 | Now change the text content to "version 2 of my text" and add it to ipfs. You will get a different hash. 89 | 90 | As you confirmed in the previous step, you can add the new text directly to IPFS or you can modify mytextfile.txt and add it to IPFS. You will get the same hash either way. 91 | 92 | ```sh 93 | $ echo "version 2 of my text" | ipfs add 94 | added QmTudJSaoKxtbEnTddJ9vh8hbN84ZLVvD5pNpUaSbxwGoa QmTudJSaoKxtbEnTddJ9vh8hbN84ZLVvD5pNpUaSbxwGoa 95 | ``` 96 | 97 | ### Step 5: Pipe content from IPFS into a File 98 | 99 | You can read this content (any version) out of ipfs and write it into a file. For example, you can toggle the contents of mytextfile.txt from "version 1" to "version 2" and back as many times as you want: 100 | 101 | ```sh 102 | $ ipfs cat QmTudJSaoKxtbEnTddJ9vh8hbN84ZLVvD5pNpUaSbxwGoa > mytextfile.txt 103 | $ cat mytextfile.txt 104 | version 2 of my text 105 | $ ipfs cat QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy > mytextfile.txt 106 | $ cat mytextfile.txt 107 | version 1 of my text 108 | ``` 109 | 110 | You can also write the content from ipfs into a completely new file. 111 | 112 | ```sh 113 | $ ipfs cat QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy > anothertextfile.txt 114 | $ cat anothertextfile.txt 115 | version 1 of my text 116 | ``` 117 | 118 | ## Explanation 119 | 120 | IPFS tracks content based on its cryptographic hash. **This hash uniquely identifies exactly that content.** As long as the content stays the same, the hash stays the same. If the content changes at all you will get a different hash. 121 | 122 | If you have two different files that contain identical content, IPFS will track that content with one hash. The filenames are different, but the content is the same, so the hash of the content will be identical. 123 | 124 | This leads to the question: how does IPFS track file names? That's the topic of the next lesson. 125 | 126 | ## Next Lesson: Add Filenames and Directory Info to IPFS 127 | 128 | Proceed to the next lesson to learn how to 129 | [Wrap Filenames and Directory Info around Content in IPFS](/files-on-ipfs/lessons/wrap-directories-around-content.md) 130 | -------------------------------------------------------------------------------- /files-on-ipfs/lessons/pin-files.md: -------------------------------------------------------------------------------- 1 | # Lesson: Making sure that a file persists in your IPFS Repository 2 | 3 | ## Goals 4 | 5 | This lesson covers the topic of "pinning" files in your IPFS repository and removing files with the ipfs garbage collector. Pinning is a very important concept in IPFS. Pinning is the mechanism that allows you to tell IPFS to always keep a given object local. 6 | 7 | After doing this Lesson you will be able to 8 | * Tell IPFS to hold onto specific files in your local IPFS repository 9 | * Tell IPFS to clean up unwanted files from your local IPS repository 10 | 11 | ## Steps 12 | 13 | ### Step 1: Create the file you're going to add and pin 14 | 15 | Create a file called `foo.txt` and put the text "ipfs rocks" in it. Here is an easy way to do this on the command line: 16 | 17 | ```sh 18 | $ echo "ipfs rocks" > foo.txt 19 | ``` 20 | 21 | ### Step 2: Add the file to IPFS 22 | 23 | ```sh 24 | $ ipfs add foo.txt 25 | added QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy foo.txt 26 | ``` 27 | 28 | ### Step 3: List objects pinned to local storage 29 | 30 | ```sh 31 | $ ipfs pin ls --type=all 32 | QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy recursive 33 | QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 indirect 34 | ``` 35 | 36 | The first object listed above is the `foo.txt` file. Objects added through `ipfs add` are pinned recursively by default. 37 | 38 | There are three types of pins in the ipfs world: 39 | 40 | a) direct pins, which pin just a single block, and no others in relation to it; 41 | 42 | b) recursive pins, which pin a given block and all of its children; 43 | 44 | c) indirect pins, which are the result of a given block's parent being pinned recursively. 45 | 46 | ### Step 4: Unpin an object 47 | 48 | You can unpin `foo.txt` like this: 49 | 50 | ```sh 51 | $ ipfs pin rm QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy 52 | unpinned QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy 53 | ``` 54 | 55 | Ok, now verify that it no longer exists: 56 | 57 | ```sh 58 | $ ipfs cat QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy 59 | ipfs rocks 60 | ``` 61 | 62 | Wait, it still appears to be there! Ok, you must run the garbage collector and then verify again: 63 | 64 | ```sh 65 | $ ipfs repo gc 66 | removed QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy 67 | $ ipfs cat QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy 68 | Error: merkledag: not found 69 | ``` 70 | 71 | IPFS has a fairly aggressive caching mechanism that will keep an object local for a short time after you perform any ipfs operation on it, but these objects may get garbage collected fairly regularly. 72 | 73 | A pinned object cannot be garbage collected, if you don't believe me try this: 74 | 75 | ```sh 76 | $ ipfs add foo.txt 77 | added QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy foo.txt 78 | $ ipfs repo gc 79 | $ ipfs cat QmRTV3h1jLcACW4FRfdisokkQAk4E4qDhUzGpgdrd4JAFy 80 | ipfs rocks 81 | ``` 82 | 83 | ## Explanation 84 | 85 | IPFS nodes treat the data they store like a cache, meaning that there is no guarantee that the data will continue to be stored. Pinning a CID (hash) tells an IPFS node that the data is important and mustn’t be thrown away. You should pin any content you consider important, to ensure that content is retained long-term. Since data important to someone else may not be important to you, pinning lets you have control over the disk space and data retention you need. 86 | 87 | ## Next Steps 88 | Next, proceed to the [Going Online](../../going-online/README.md) tutorial. 89 | -------------------------------------------------------------------------------- /files-on-ipfs/lessons/wrap-directories-around-content.md: -------------------------------------------------------------------------------- 1 | # Lesson: Wrap Filenames and Directory Info around Content in IPFS 2 | 3 | ## Goals 4 | After doing this Lesson you will be able to 5 | * Add a file to IPFS, including its filename, permissions, etc. 6 | * Add directories to IPFS 7 | * Explain how IPFS represents two files that have identical content 8 | * Read content out of IPFS using the hash of a directory that contains the file 9 | 10 | ## Steps 11 | 12 | ### Step 1: Create the file you're going to add 13 |
14 | You may already have this file from the previous lesson. If you do, make sure the content of the file matches. Otherwise the hashes you get won't match the examples in this lesson. 15 |
16 | 17 | Create a file called `mytextfile.txt` and put the text "version 1 of my text" in it. Here is an easy way to do this on the command line: 18 | 19 | ```sh 20 | $ echo "version 1 of my text" > mytextfile.txt 21 | ``` 22 | 23 | ### Step 2: Add the file to IPFS 24 | 25 | ```sh 26 | $ ipfs add -w mytextfile.txt 27 | added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy mytextfile.txt 28 | added QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w 29 | ``` 30 | 31 | In the previous lesson, when you ran `ipfs add mytextfile.txt` without the `-w` flag, ipfs only returned one hash. This time it returned two hashes. The first hash `QmZtmD2...` is the same as before — it's the hash of the content _inside_ the file. The second hash `QmPvaEQF...` is the hash of the directory and filename information that ipfs "wrapped" around our content. 32 | 33 | In the next steps, you will use ipfs commands to see what that directory and filename information looks like and how you can use it. 34 | 35 | ### Step 3: List the directory information 36 | 37 | The `-w` flag tells ipfs to include the directory and filename information along with the content — it "wraps the file in a directory". For more info about this, run `ipfs add --help` and read the description there. 38 | 39 | To list this directory and filename information, use `ipfs ls`. You will use the `-v` flag to include header information. To learn more about this command, run `ipfs ls --help` 40 | 41 | ```sh 42 | $ ipfs ls -v QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w 43 | Hash Size Name 44 | QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy 29 mytextfile.txt 45 | ``` 46 | 47 | This command `ipfs ls QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w` translates to "list the files referenced by the directory whose hash is QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w". 48 | 49 | The response shows that the directory contains one file — "mytextfile.txt" — and the hash of that file's content is `QmZtmD2q...` 50 | 51 |
52 | Note that you had to use ipfs ls instead of ipfs cat to read this info because it's a directory. If you try to read the directory using ipfs cat you will get an error: 53 | 54 |
55 | $ ipfs cat QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w
56 | Error: this dag node is a directory
57 | 
58 |
59 | 60 | 61 | ### Step 4: Read the File's contents using the parent directory's hash 62 | 63 | You can use the directory's hash to read the file's content like this: 64 | 65 | ```sh 66 | $ ipfs cat QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w/mytextfile.txt 67 | version 1 of my text 68 | ``` 69 | 70 | This command translates to "return the content that's referred to as `mytextfile.txt` within the directory whose hash is QmPvaEQFVvuiaYzkSVUp23iHTQeEUpDaJnP8U7C3PqE57w" 71 | 72 | ## Bonus Steps 73 | 74 | Some things to try: 75 | 76 | 1. Create a directory with multiple files. Tell ipfs to recursively add the directory and all of its files. 77 | 2. Create two different files with the same content. Add them both to ipfs with `ipfs add -w` and confirm that ipfs is re-using the hash of that content when it builds the directory and filename information. 78 | 79 | ## Explanation 80 | 81 | When you add a file to your ipfs repository, ipfs calculates the cryptographic hash of the file's contents and returns that hash to you. You can then use the hash to reference the file's contents and read them back out of the ipfs repository. 82 | 83 | In order to keep track of information like filenames and paths, ipfs lets you "wrap" directory and filename information around the file contents you've added. The directory and filename information has its own hashes. This makes it possible to retrieve content from the ipfs repository using "ipfs paths" that are a combination of hashes, filenames and directory names. 84 | 85 | ## Next Steps 86 | 87 | Next, learn how to [Tell IPFS to Keep a File](pin-files.md) 88 | -------------------------------------------------------------------------------- /going-online/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Going Online - Joining the Distributed Web 2 | 3 | ## Prerequisites 4 | 5 | To do the lessons in this tutorial you must: 6 | * Be familiar with using the command line 7 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 8 | 9 | ## Learning Objectives 10 | These Lessons will teach you how to 11 | * Connect your local IPFS node to the IPFS network 12 | * Find/examine Peers on the IPFS network 13 | * Retrieve content from a Peer on the IPFS network 14 | 15 | ## Key Concepts 16 | * Connecting and interacting with the IPFS network 17 | 18 | ## Lessons 19 | 20 | 1. [Lesson: Connect your node to the IPFS network](/going-online/lessons/connect-your-node.md) 21 | 2. [Lesson: Find Peers on the Network](/going-online/lessons/find-peers.md) 22 | 3. [Lesson: Retrieve content from a Peer](/going-online/lessons/retrieve-from-peer.md) 23 | 24 | -------------------------------------------------------------------------------- /going-online/lessons/connect-your-node.md: -------------------------------------------------------------------------------- 1 | # Lesson: Connect your node to the IPFS network 2 | 3 | This lesson shows how to connect the IPFS node on your local computer to the IPFS network, or “_the swarm_”. Everything that you have done so far has been done locally. Now it gets a lot more interesting! 4 | 5 | ## Prerequisites 6 | To do the steps in this lesson you must: 7 | * Be familiar with using the command line 8 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 9 | 10 | ## Goals 11 | 12 | After doing this Lesson you will be able to 13 | * Start the IPFS daemon to connect your local node to the IPFS network 14 | 15 | ## Steps 16 | 17 | ### Step 1: Start the IPFS daemon 18 | 19 | Start the IPFS daemon by running 20 | 21 | ```sh 22 | $ ipfs daemon 23 | ``` 24 | 25 | You will see output from the daemon like the following: 26 | 27 | ```sh 28 | Initializing daemon... 29 | go-ipfs version: 0.5.0-dev-17e886e29 30 | Repo version: 7 31 | System version: amd64/linux 32 | Golang version: go1.13.5 33 | Swarm listening on /ip4/12.2.0.36/tcp/4001 34 | Swarm listening on /ip4/127.0.0.1/tcp/4001 35 | Swarm listening on /ip6/::1/tcp/4001 36 | Swarm listening on /p2p-circuit 37 | Swarm announcing /ip4/12.2.0.36/tcp/4001 38 | Swarm announcing /ip4/127.0.0.1/tcp/4001 39 | Swarm announcing /ip6/::1/tcp/4001 40 | API server listening on /ip4/127.0.0.1/tcp/5001 41 | WebUI: http://127.0.0.1:5001/webui 42 | Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080 43 | Daemon is ready 44 | ``` 45 | 46 | Notice that if you [added files](/files-on-ipfs/lessons/add-and-retrieve-file-content.md) before running the daemon, the blocks will be advertised after a few seconds when the reprovider runs. 47 | 48 | ### Step 2: Examine your ipfs node id info 49 | 50 | Let's look at the details of your connections made by the daemon with `ipfs id`. Open up another command line and run: 51 | 52 | ```sh 53 | $ ipfs id 54 | { 55 | "ID": "QmRX....xQTp", 56 | "PublicKey": "CAAS....AAE=", 57 | "Addresses": [ 58 | "/ip4/127.0.0.1/tcp/4001/ipfs/QmRX....xQTp", 59 | "/ip4/12.2.0.36/tcp/4001/ipfs/QmRX....xQTp", 60 | "/ip6/::1/tcp/4001/ipfs/QmRX....xQTp", 61 | "/ip6/2802:285:8360:da70::9191/tcp/4001/ipfs/QmRX....xQTp", 62 | "/ip6/2802:285:8360:da70:5146:9a0a:e910:19c3/tcp/4001/ipfs/QmRX....xQTp", 63 | "/ip6/2802:285:8360:da70:ccb4:bd10:baa3:d022/tcp/4001/ipfs/QmRX....xQTp", 64 | "/ip4/83.24.208.218/tcp/26521/ipfs/QmRX....xQTp" 65 | ], 66 | "AgentVersion": "/go-ipfs/0.5.0-dev/17e886e29", 67 | "ProtocolVersion": "ipfs/0.1.0" 68 | } 69 | ``` 70 | Note: The hashes above have been shortened for readability. 71 | 72 | The "ID" field is your Peer ID, used to uniquely identify your node on the IPFS network. The "PublicKey" field goes along with your Peer ID, used under-the-hood by IPFS for public key cryptography. The "Addresses" shown are an array of IP addresses used for IPFS network traffic. Addresses using TCP port 4001 are known as "swarm addresses" that your local daemon will listen on for connections from other IPFS peers. 73 | 74 | ### Step 3: Shutdown the daemon 75 | 76 | You may shut down the daemon by typing Ctrl-C in the command line that you started with: 77 | 78 | ```sh 79 | ... 80 | Daemon is ready 81 | ^C 82 | Received interrupt signal, shutting down... 83 | (Hit ctrl-c again to force-shutdown the daemon.) 84 | ``` 85 | 86 | Note: You may run the IPFS daemon as a background process using the command `ipfs daemon &`. If you want to stop the background process just type `fg` (foreground) to bring that process to the foreground and stop it with Ctrl-C. 87 | 88 | ```sh 89 | $ ipfs daemon & 90 | pid 8469 91 | $ Initializing daemon... 92 | go-ipfs version: 0.5.0-dev-17e886e29 93 | Repo version: 7 94 | System version: amd64/linux 95 | Golang version: go1.13.5 96 | Swarm listening on /ip4/10.0.0.35/tcp/4001 97 | ... 98 | Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080 99 | Daemon is ready 100 | fg 101 | ipfs daemon 102 | ^C 103 | Received interrupt signal, shutting down... 104 | (Hit ctrl-c again to force-shutdown the daemon.) 105 | ``` 106 | 107 | ## Explanation 108 | 109 | You run the IPFS daemon in order to have your local IPFS node become part of the IPFS network and listen to other IPFS peers. 110 | 111 | ## Next Lesson: Find Peers on the Network 112 | 113 | Proceed to the next lesson to learn how to 114 | [Find Peers on the Network](/going-online/lessons/find-peers.md) 115 | -------------------------------------------------------------------------------- /going-online/lessons/find-peers.md: -------------------------------------------------------------------------------- 1 | # Lesson: Find Peers on the Network 2 | 3 | This lesson shows how to find and examine the peers you connect to on the IPFS network. You will use the `ipfs swarm` and `ipfs id` tools for this purpose. The swarm is the component that opens, listens for, and maintains connections to other IPFS peers. You can also examine connected peers and the network using the Web UI. 4 | 5 | ## Prerequisites 6 | To do the steps in this lesson you must: 7 | * Be running the `ipfs daemon` 8 | 9 | ## Goals 10 | 11 | After doing this Lesson you will be able to 12 | * Find and examine peers on the IPFS network 13 | 14 | ## Steps 15 | 16 | ### Step 1: Start the IPFS daemon 17 | 18 | Start the IPFS daemon by running 19 | 20 | ```sh 21 | $ ipfs daemon 22 | ``` 23 | 24 | ### Step 2: Find peers that we are connected to 25 | 26 | You can use the command `ipfs swarm peers` to examine for connected peers: 27 | 28 | ```sh 29 | $ ipfs swarm peers 30 | /ip4/147.75.69.143/tcp/4001/ipfs/QmNn....GAJN 31 | /ip4/147.75.83.83/tcp/4001/ipfs/QmbL....75Nb 32 | /ip4/147.75.85.167/tcp/4001/ipfs/QmXA....qhfW 33 | /ip6/2604:1380:0:c100::1/tcp/4001/ipfs/QmQC....uLTa 34 | /ip6/2604:1380:3000:1f00::1/tcp/4001/ipfs/QmcZ....3dwt 35 | /ip6/2604:1380:40b0:c00::3/tcp/4001/ipfs/QmYA....yYdN 36 | ``` 37 | 38 | ### Step 3: Examine a connected peer 39 | 40 | You will use the `ipfs id ` command to examine a connected peer: 41 | 42 | ```sh 43 | $ ipfs id Qmf1...mx36 44 | { 45 | "ID": "Qmf1....mx36", 46 | "PublicKey": "CAAS....AAE=", 47 | "Addresses": [ 48 | "/ip4/127.0.0.1/tcp/4001", 49 | "/ip6/::1/tcp/4001", 50 | "/ip4/134.215.4.214/tcp/4001" 51 | ], 52 | "AgentVersion": "go-ipfs/0.4.21/8ca278f45", 53 | "ProtocolVersion": "ipfs/0.1.0" 54 | } 55 | ``` 56 | 57 | Note: The "ID" field shown above is the Peer's ID, and this was also the hash that was shown when you ran `ipfs swarm peers`. Peers are identified on the network directly by their Peer ID. 58 | 59 | ### Step 4: Examine using the Web UI 60 | 61 | The IPFS daemon also serves up a modern Web UI that you are able to open in a browser. Did you notice when you started the daemon that there was the following? 62 | 63 | WebUI: http://127.0.0.1:5001/webui 64 | 65 | Open the link above in your browser. You will see the Web UI displayed with sections on Status, Files, Explore, Peers, and Settings. Click on the Peers section and you will see a world map indicating the location of connected peers. Scroll down the page to see information on each of the peers, their country/city location, network latency, Peer ID, etc. Spend some time looking at the other different sections of the Web UI. 66 | 67 | ## Explanation 68 | 69 | Once you have connected to the IPFS network by running the daemon, other IPFS nodes (peers) will begin to connect and communicate with your node. Using the commands `ipfs swarm` and `ipfs id` allows you to examine the connected nodes. The Web UI also shows in-depth information about peers. 70 | 71 | ## Next Lesson: Retrieve content from a Peer 72 | 73 | Proceed to the next lesson to learn how to 74 | [Retrieve content from a Peer](/going-online/lessons/retrieve-from-peer.md) 75 | -------------------------------------------------------------------------------- /going-online/lessons/retrieve-from-peer.md: -------------------------------------------------------------------------------- 1 | # Lesson: Retrieve content from a Peer 2 | 3 | This lesson shows how to use an IPFS node on your computer to request content from other peers on the network. Some of the underlying topics are covered in greater depth in the tutorials about [Files on IPFS](files-on-ipfs/README.md). 4 | 5 | ## Prerequisites 6 | To do the steps in this lesson you must: 7 | * Be familiar with using the command line 8 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 9 | 10 | ## Goals 11 | 12 | After doing this Lesson you will be able to 13 | * Access any content through your local IPFS node using its command line interface 14 | 15 | ## Steps 16 | 17 | ### Step 1: Start the IPFS daemon 18 | 19 | Start the IPFS daemon by running 20 | 21 | ```sh 22 | $ ipfs daemon 23 | ``` 24 | 25 | If the daemon is not running, your IPFS node won't be able to retrieve content from other nodes on the network. 26 | 27 | ### Step 2: Read the content on the command line 28 | 29 | You can use the command line to request content from your IPFS node. If the node does not have a copy of that content, it will attempt to find another peer node that does have the content. For example, the IPFS team have [published a snapshot of the turkish version of wikipedia](https://ipfs.io/blog/24-uncensorable-wikipedia/). The hash of that snapshot, which contains about 15GB of Turkish-language wikipedia pages, is `Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1`. We can use the command line to have your IPFS node read pages from that snapshot. 30 | 31 | ``` 32 | # get the article about "Peer to Peer" 33 | ipfs cat Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/Peer-to-peer.html > Peer-to-peer.html 34 | 35 | # explore the articles in the snapshot 36 | ipfs ls -v -s Qme2sLfe9ZMdiuWsEtajWMDzx6B7VbjzpSC2VWhtB6GoB1/wiki/ 37 | ``` 38 | 39 | If you're not familiar with the `ipfs cat` and `ipfs ls` commands they are explained in the [Tutorial about Files on IPFS](/files-on-ipfs/README.md) 40 | 41 | ## Explanation 42 | 43 | You can use a local IPFS node to read content from the worldwide IPFS network. One way to do this is through the command line using commands like `ipfs cat` and `ipfs ls`. When you pass the content-addressed (hash) identifiers of the content you want into these commands, your IPFS node will check to see if it has a local copy of the content you're requesting. If your node has a local copy, it will return that content to you immediately. If your node does not have a local copy, it will attempt to find a peer on the IPFS network that does have the content. As long as _at least one peer_ has the content you want, your IPFS node will be able to find that peer, retrieve the content from the peer, and return that content to you. 44 | 45 | This is the essential function of an IPFS node. It uses content-addressed (hash) identifiers to find content on the peer to peer network. It also provides that content to other peers who want it. 46 | 47 | ## Next Steps 48 | 49 | This lesson covered how to use the command line to request content from your IPFS node, but there are many other ways to interact with IPFS nodes. If you want to learn about the many other ways you can use IPFS to access the same content using the same content-addressed link, go to the [Tutorial on The Myriad Ways to Access and Distribute IPFS Content](../../avenues-for-access/README.md). 50 | 51 | Otherwise, proceed to the next lesson [Interacting with the Classical (HTTP) Web](../../classical-web/README.md) 52 | -------------------------------------------------------------------------------- /images/railsbridge-format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipfs-shipyard/ipfs-primer/af7c2b9d4ef3cf8a3fadcea56acfc311591fe483/images/railsbridge-format.png -------------------------------------------------------------------------------- /install-ipfs/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Install and Initialize IPFS 2 | These Lessons are tested with go-ipfs version 0.5.0. _Please update this file on github to reflect any other versions that have been tested._ 3 | 4 | ## Prerequisites 5 | 6 | - You should have some familiarity with the commandline 7 | 8 | ## Learning Objectives 9 | These Lessons will teach you how to 10 | * Install IPFS 11 | * Initialize an IPFS repository 12 | * Locate where IPFS stores the contents of your local IPFS repository 13 | 14 | ## Key Concepts 15 | * IPFS Repositories 16 | 17 | ## Lessons 18 | 19 | 1. [Lesson: Download and Install IPFS](/install-ipfs/lessons/download-and-install.md) 20 | 2. [Lesson: Initialize your IPFS Repository](/install-ipfs/lessons/initialize-repository.md) 21 | 22 | ## Next Steps 23 | 24 | Once you know how to add files to IPFS and retrieve them, you will be ready to share those files on the P2P network following the [Tutorial: Going Online - Joining the Distributed Web](/going-online/README.md) 25 | 26 | If you're wondering how to update those files after you've shared them, see the [Tutorial: Publishing Changes on the Permanent Web](/publishing-changes/README.md) 27 | 28 | If you want to see how to access those files from the conventional HTTP web, go to the [Tutorial: Interacting with the Classical (HTTP) Web](/classical-web/README.md) 29 | -------------------------------------------------------------------------------- /install-ipfs/lessons/download-and-install.md: -------------------------------------------------------------------------------- 1 | # Lesson: Download and Install IPFS 2 | 3 | ## Goals 4 | 5 | After doing this Lesson you will be able to 6 | * Download IPFS and install it on your operating system 7 | * Display which version of IPFS you're using 8 | * Get a list of commands the ipfs binary supports 9 | 10 | 11 | ## Steps 12 | 13 | ### Step 1: Download the Prebuilt IPFS Package 14 | Visit the IPFS installation page at https://docs.ipfs.io/guides/guides/install/ and download the prebuilt ipfs binaries for your operating system. 15 | 16 | **Why does the installation page talk about "Go IPFS"?** There are multiple implementations of the IPFS protocol. The core IPFS team maintain implementations in Golang and Javascript. Those are commonly referred to as [go-ipfs](https://github.com/ipfs/go-ipfs) and [js-ipfs](https://github.com/ipfs/js-ipfs). The official binaries are built from the Go implementation. 17 | 18 | ### Step 2: Unzip the Prebuilt Package 19 | 20 | The binaries for Mac OSX and Linux are in a gzipped tar format (`.tar.gz`). The binaries for Windows are in a zip file. Use the appropriate tool to unzip the file. There are some hints on https://docs.ipfs.io/guides/guides/install/ under the heading _Installing from a Prebuilt Package_ 21 | 22 | This will create a directory called go-ipfs. 23 | ```bash 24 | LICENSE README.md build-log install.sh ipfs 25 | ``` 26 | 27 | The file named `ipfs` is your executable ipfs binary. 28 | 29 | ### Step 3: Install the IPFS Binary on your executable path 30 | 31 | To install the binary, all you need to do is put the `ipfs` binary file somewhere on your executable PATH. 32 | 33 | **Note about permissions**: Whichever approach you use to install the binary, make sure you have the necessary permissions. On Mac OSX or Linux, you probably want to use [sudo](https://www.sudo.ws/), which is already installed on most systems. 34 | 35 | If you're on Mac OSX or Linux, you can use the provided install script by running 36 | 37 | ```bash 38 | cd go-ipfs 39 | sudo ./install.sh 40 | ``` 41 | 42 | Read the output from running this. If it complains about being unable to write the file, you need to deal with permissions (see the note above about permissions) 43 | 44 | ### Step 4: Display the IPFS version 45 | 46 | When you're troubleshooting, it's important to know which version of ipfs you're using. To find out the current version, run 47 | 48 | ```sh 49 | $ ipfs version 50 | ``` 51 | 52 | ### Step 5: Display the IPFS help page and list of commands 53 | 54 | If you need help remembering how to use any ipfs commands, run 55 | 56 | ```sh 57 | $ ipfs help 58 | ``` 59 | 60 | This should display information beginning with 61 | 62 | ```sh 63 | USAGE: 64 | 65 | ipfs - Global p2p merkle-dag filesystem. 66 | ... 67 | ``` 68 | 69 | For a complete list of commands that the ipfs executable supports, run 70 | ```sh 71 | $ ipfs commands 72 | ``` 73 | 74 | ## Next Steps 75 | 76 | Next, [Initialize your IPFS Repository](initialize-repository.md) 77 | -------------------------------------------------------------------------------- /install-ipfs/lessons/initialize-repository.md: -------------------------------------------------------------------------------- 1 | # Lesson: Initialize your IPFS Repository 2 | 3 | ## Goals 4 | 5 | After doing this Lesson you will be able to 6 | 7 | * Initialize a local ipfs repository 8 | * Locate where IPFS stores the contents of your local IPFS repository 9 | * Open the IPFS Configuration file 10 | 11 | ## Steps 12 | 13 | ### Step 1: Initialize the Repository 14 | 15 | Use the `ipfs init` command to initialize the repository. This will generate a local ipfs repository for the current user account on your machine. It also generates a cryptographic keypair that allows your ipfs node to cryptographically sign the content and messages that you create. 16 | 17 | ```sh 18 | $ ipfs init 19 | initializing ipfs node at /Users/jbenet/.go-ipfs 20 | generating 2048-bit RSA keypair...done 21 | peer identity: Qmcpo2iLBikrdf1d6QU6vXuNb6P7hwrbNPW9kLAH8eG67z 22 | to get started, enter: 23 | 24 | ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme 25 | 26 | ``` 27 | 28 |
29 | Note: If you have already initialized ipfs on your machine, you will get an error message like: 30 | 31 |
 32 | initializing ipfs node at /Users/sally/.ipfs
 33 | Error: ipfs configuration file already exists!
 34 | Reinitializing would overwrite your keys.
 35 | 
36 | 37 | This is ok. It means you've already done this step. You can safely proceed to Step 2. 38 |
39 | 40 | ### Step 2: Use IPFS to explore the post-install documentation 41 | 42 |
43 | If you installed a different version of ipfs, you may have gotten a slightly different path to use here. Either path will work for this tutorial. The path you got from the ipfs init command will give you documentation that's accurate for the version of ipfs you're using. 44 |
45 | 46 | When you ran `ipfs init`, it provided a hint for how you can get started. It said: 47 | ```bash 48 | to get started, enter: 49 | 50 | ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme 51 | 52 | ``` 53 | 54 | This `ipfs cat` command tells ipfs to read the content matching the path you provided. If the content isn't available locally, ipfs will attempt to find it on the peer-to-peer network. 55 | 56 | In order to run the following command, the ipfs daemon must be running. In order to run the ipfs daemon, type `ipfs daemon &`. This will start the ipfs daemon and place it into the background of your current console. 57 | 58 | ```sh 59 | $ ipfs daemon & 60 | ``` 61 | 62 | Run the `ipfs cat` command with the path you got from the init message: 63 | 64 | ```sh 65 | $ ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme 66 | ``` 67 | 68 | You should see something like this: 69 | 70 | ``` 71 | Hello and Welcome to IPFS! 72 | 73 | ██╗██████╗ ███████╗███████╗ 74 | ██║██╔══██╗██╔════╝██╔════╝ 75 | ██║██████╔╝█████╗ ███████╗ 76 | ██║██╔═══╝ ██╔══╝ ╚════██║ 77 | ██║██║ ██║ ███████║ 78 | ╚═╝╚═╝ ╚═╝ ╚══════╝ 79 | 80 | If you're seeing this, you have successfully installed 81 | IPFS and are now interfacing with the ipfs merkledag! 82 | 83 | ------------------------------------------------------- 84 | | Warning: | 85 | | This is alpha software. use at your own discretion! | 86 | | Much is missing or lacking polish. There are bugs. | 87 | | Not yet secure. Read the security notes for more. | 88 | ------------------------------------------------------- 89 | 90 | Check out some of the other files in this directory: 91 | 92 | ./about 93 | ./help 94 | ./quick-start <-- usage examples 95 | ./readme <-- this file 96 | ./security-notes 97 | 98 | ``` 99 | 100 | You can explore other objects in there. For example, check out `security-notes`: 101 | 102 | 103 | ```sh 104 | ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/security-notes 105 | ``` 106 | 107 | ### Step 3: Locate where IPFS Stores the Repository Contents on your Machine 108 | 109 | `ipfs` stores its local object repository in `~/.ipfs` 110 | 111 | ```sh 112 | $ ls ~/.ipfs 113 | ``` 114 | 115 | The contents of that directory look like this: 116 | 117 | ```sh 118 | blocks config datastore version 119 | ``` 120 | All of the contents of your IPFS repository are stored within this directory. For example, the readme file from above is stored in here, along with the other files it links to. You can run a grep to find out the exact location. 121 | 122 | ### Step 4: Open the IPFS Configuration file 123 | 124 | The configuration for your ipfs repository is in a json file that's usually stored at `~/.ipfs/config`. To view the current config, run: 125 | 126 | ```sh 127 | $ ipfs config show 128 | ``` 129 | One of the useful details in this config file is at `Datastore.Path`. This tells you where the ipfs repository's contents are being stored. As we saw in Step 3, this is usually `~/.ipfs` 130 | 131 | ## Next Steps 132 | 133 | Next, proceed to the [Files on IPFS](../../files-on-ipfs) tutorial. 134 | -------------------------------------------------------------------------------- /ipfs-dag/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Merkle Trees and the IPFS DAG 2 | 3 | ## Concepts 4 | These Lessons introduce the following concepts: 5 | * Cryptographic Hashes and Content Addressability 6 | * Authenticated Graphs 7 | * Turning Files into Trees 8 | * Turning any Data into Trees 9 | * Publishing hashes on the DHT 10 | * Getting data from the Peer to Peer Network 11 | 12 | ## Prerequisites 13 | 14 | ## Lessons 15 | 1. [Lesson: Turn a File into a Tree of Hashes](/ipfs-dag/lessons/files-as-dags.md) 16 | 2. [Lesson: The Cryptographic Hash](/ipfs-dag/lessons/crypto-hash.md) 17 | 3. [Lesson: Build a Tree of Data in IPFS Using Cryptographic Hashes to Link the Pieces (a Merkle DAG)](/ipfs-dag/lessons/blocks-from-scratch.md) 18 | -------------------------------------------------------------------------------- /ipfs-dag/lessons/blocks-from-scratch.md: -------------------------------------------------------------------------------- 1 | # Lesson: Creating a Merkle Tree from Scratch 2 | 3 | *Work in Progress* _This is the content from [this existing Lesson](https://ipfs.io/ipfs/QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7/data/readme.md) vaguely re-framed to fit the Lesson framework._ 4 | 5 | ## Goals 6 | * Build a tree of data in IPFS using cryptographic hashes to link the pieces (a Merkle DAG) 7 | 8 | ## Explanation: Blocks vs Objects 9 | In ipfs, a block refers to a single unit of data, identified by its key (hash). 10 | a block can be any sort of data, and does not necessarily have any sort of 11 | format associated with it. an object, on the other hand, refers to a block that 12 | follows the merkledag protobuf data format. it can be parsed and manipulated 13 | via the `ipfs object` command. any given hash may represent an object or a block. 14 | 15 | # Steps 16 | ## Step 1 17 | Creating your own blocks is easy! simply put your data in a file and run 18 | `ipfs block put ` on it, or you can pipe your filedata into 19 | `ipfs block put`, like so: 20 | 21 | ## Step 2 22 | ``` 23 | $ echo "This is some data" | ipfs block put 24 | QmfQ5QAjvg4GtA3wg3adpnDJug8ktA1BxurVqBD8rtgVjM 25 | $ ipfs block get QmfQ5QAjvg4GtA3wg3adpnDJug8ktA1BxurVqBD8rtgVjM 26 | This is some data 27 | ``` 28 | Note: When making your own block data, you wont be able to read the data with 29 | `ipfs cat`, this is because you are inputting raw data without the unixfs data 30 | format. To read raw blocks use `ipfs block get` as shown in the example. 31 | -------------------------------------------------------------------------------- /ipfs-dag/lessons/crypto-hash.md: -------------------------------------------------------------------------------- 1 | # Lesson: The Cryptographic Hash 2 | 3 | ## Goals 4 | * Learn about cryptographic hashes, their history and characteristics 5 | 6 | ## Characteristics of cryptographic hashes 7 | 8 | Cryptographic hashes are seen as long strings of alphabetic and numeric data. They are created by having data presented as input to a _cryptographic hash function_, which processes that data and writes out a hash value, or checksum. The input data may be of arbitrary length, but the ouput hash is always of a fixed length. 9 | 10 | Cryptographic hashes have a number of very important characteristics: 11 | * **Deterministic** - the same input message always returns exactly the same output hash 12 | * **Uncorrelated** - a small change in the message should generate a completely different hash 13 | * **Unique** - it’s not possible to generate the same hash from two different messages 14 | * **One-way** - it’s not possible to guess or calculate the input message from its hash 15 | 16 | Let's examine these characteristics: 17 | 18 | **Deterministic:** So long as you use the same cryptographic hash function, you will always get the exact same output hash value for the same input data. This allows you to verify the authenticity of the data that you might have in a file, for example. If two files have the same output hash when processed with the same cryptographic hash function, then the data can be believed to be identical. 19 | 20 | **Uncorrelated:** A small change to the input data should generate a completely different hash. In this way the two hashes should appear uncorrelated. You can demonstrate this for yourself on the command line: 21 | 22 | ```sh 23 | $ echo "Abracadabra!" | ipfs add 24 | added QmWyVG3yhEu8o6EMbUTxcFdzSkddN2NobJye1LhuNajaxy 25 | $ echo "abracadabra!" | ipfs add 26 | added QmdFyNVLCtWxyJDr9osNWMoY6CrnDQQRT8Ypa6MBpkjap3 27 | ``` 28 | 29 | Notice the huge difference in the two hashes above. By changing the first character 'A' to lower-case 'a', the hash function generated very different output. 30 | 31 | **Unique:** It's not possible to generate the same hash from two different messages. This is a characteristic of a well-built, robust cryptographic hash function. It is possible that some hash functions can derive the same hash for different messages, and this is called a _hash collision_. Hash functions have evolved over time, primarily due to vulnerabilities and weaknesses that were found. Modern cryptographic hash functions are known for _strong collision resistance_. Much work has been put into the attacking of cryptographic hash functions in particular, as they are considered key building blocks of modern cryptography. 32 | 33 | **One-way:** It’s not possible to guess or calculate the input message from its hash. In other words, you cannot reverse or invert a hash function to obtain the original message that it was computed from. Hence, a cryptographic hash function is considered a _one-way function_. Brute-force attack methods sometimes are used to try to find a message that matches a given hash. The use of rainbow tables (pre-computed values from known inputs) is another common attack. 34 | 35 | ## History of cryptographic hashes 36 | 37 | **MD5:** Designed by Ron Rivest in 1991 to replace an earlier hash function MD4. "MD" stands for "Message Digest". Produces a hash of 128 bits (16 bytes). Suitable for non-cryptographic uses, such as basic data integrity. Collisions against MD5 can be calculated within seconds which makes the algorithm unsuitable as a cryptographic hash. 38 | 39 | **SHA-1:** Developed as part of the U.S. Government's Capstone project. The original specification of the algorithm was published in 1993. "SHA" stands for "Secure Hash Algorithm". Produces a hash of 160 bits (20 bytes). Collisions against SHA-1 have been produced and this hash function should be considered broken. 40 | 41 | **SHA-2:** Designed by the United States National Security Agency (NSA), first published in 2001. SHA-2 basically consists of two hash algorithms: SHA-256 and SHA-512. SHA-512 is more secure than SHA-256. There are a number of variants of both algorithms. SHA-256 produces a hash of 256 bits (32 bytes) and SHA-512 produces a hash of 512 bits (64 bytes). 42 | 43 | **SHA-3:** Released by NIST in 2015. SHA-3 is a subset of the broader cryptographic primitive family Keccak. SHA-3 has the same output sizes as SHA-2: 224, 256, 384 and 512 bits. 44 | 45 | [Read more on Cryptographic Hash Functions](https://en.wikipedia.org/wiki/Cryptographic_hash_function) 46 | 47 | ## Next Steps 48 | 49 | Next, learn how to [Build a Tree of Data in IPFS Using Cryptographic Hashes to Link the Pieces (a Merkle DAG)](/ipfs-dag/lessons/blocks-from-scratch.md) 50 | 51 | -------------------------------------------------------------------------------- /ipfs-dag/lessons/files-as-dags.md: -------------------------------------------------------------------------------- 1 | # Lesson: Turn a File into a Merkle Tree 2 | 3 | *Work in Progress* _This is the content from [this existing Lesson](https://ipfs.io/ipfs/QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/example#/ipfs/QmQwAP9vFjbCtKvD8RkJdCvPHqLQjZfW7Mqbbqx18zd8j7/data/readme.md) vaguely re-framed to fit the Lesson framework._ 4 | 5 | ## Goals 6 | * Explain how IPFS represents Files as Merkle trees 7 | * Explore the Merkle Tree Blocks that make up a File in IPFS 8 | 9 | ## Steps 10 | 11 | ### Step 1: Download the sample file and add it to IPFS 12 | 13 | For this lesson we need a file that's larger than 256kb. Download this image: [tree-in-cosmos.jpg](https://raw.githubusercontent.com/ipfs-shipyard/ipfs-primer/master/samples/tree-in-cosmos.jpg) (863kb) 14 | 15 | Save it as "tree-in-cosmos.jpg" and then add it to IPFS 16 | 17 | ```sh 18 | $ ipfs add tree-in-cosmos.jpg 19 | added QmWNj1pTSjbauDHpdyg5HQ26vYcNWnubg1JehmwAE9NnU9 20 | ``` 21 | 22 | ### Step 2: 23 | 24 | Let's look at how IPFS represented that file internally by passing the content's hash to the `ipfs ls` command: 25 | 26 | ``` 27 | ipfs ls -v QmWNj1pTSjbauDHpdyg5HQ26vYcNWnubg1JehmwAE9NnU9 28 | Hash Size Name 29 | QmPHPs1P3JaWi53q5qqiNauPhiTqa3S1mbszcVPHKGNWRh 262158 30 | QmPCuqUTNb21VDqtp5b8VsNzKEMtUsZCCVsEUBrjhERRSR 262158 31 | QmS7zrNSHEt5GpcaKrwdbnv1nckBreUxWnLaV4qivjaNr3 262158 32 | QmQQhY1syuqo9Sq6wLFAupHBEeqfB8jNnzYUSgZGARJrYa 76151 33 | ``` 34 | 35 | This returned a bunch of hashes. That's different from what happened in the [lesson on adding file content to ipfs](../../files-on-ipfs/lessons/add-and-retrieve-file-content.md), where you only got one hash back. This is because ipfs breaks files into content _blocks_ that are each about 256kb and then uses a **hash tree** to represent how they fit together. 36 | 37 | This is one example of how IPFS uses hash trees, also known as **Merkle DAGs**, to represent information. 38 | 39 |
40 | This kind of hash tree is formally known as a Merkle DAG -- this is because the technical term for this type of data structure is a Directed Acyclic Graph, or DAG, and a mathematician named Ralph Merkle invented them. Hence: Merkle DAG, or merkledag. 41 |
42 | 43 | 44 | 45 | In this case, the hash for our file `QmWNj1pTS...` is the hash of the **root block** in a DAG that contains 4 sub-blocks. The output from `ipfs ls` lists those sub-blocks and their size. 46 | 47 | Sometimes sub-blocks have sub-blocks of their own. That's when a Merkle DAG starts looking like a tree. This diagram shows a Merkle DAG with three layers of sub-blocks.: 48 | 49 | ![Diagram of a Merkle DAG with 3 layers of sub-blocks (looks like an upside-down tree)](https://camo.githubusercontent.com/1aba273a55fdbbf8cc9acb3b07ce0fc64e2382af/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f7468756d622f392f39352f486173685f547265652e7376672f33303070782d486173685f547265652e7376672e706e67) 50 | 51 | _Do you think it looks like an upside-down tree?_ 52 | 53 | ### Step 3: Explore The Hash Tree 54 | 55 | The `ipfs refs` and `ipfs object links` commands are other ways to get the listing of sub-blocks in the tree. 56 | 57 | Try these: 58 | ```sh 59 | $ ipfs refs QmWNj1pTSjbauDHpdyg5HQ26vYcNWnubg1JehmwAE9NnU9 60 | ipfs object links -v QmWNj1pTSjbauDHpdyg5HQ26vYcNWnubg1JehmwAE9NnU9 61 | ``` 62 | 63 | If the sub-blocks had more sub-blocks within them, you would be able to use these commands to get the hashes of those sub-sub-blocks. For example: 64 | 65 | ```sh 66 | $ ipfs object links -v QmPHPs1P3JaWi53q5qqiNauPhiTqa3S1mbszcVPHKGNWRh 67 | ``` 68 | But this doesn't return anything because there aren't sub-blocks within `QmPHPs1P...` 69 | 70 | ### Step 4: Read the content back out of IPFS 71 | 72 | If you use `ipfs cat` to read the content back out of ipfs, it handles re-assembling the file from the hash tree. For example, the following command will read our sample image out of ipfs and write the content into a new file called "copy-of-tree-in-cosmos.jpg". Run the command and then open the new file to confirm that the image is still intact. 73 | 74 | ```sh 75 | $ ipfs cat QmWNj1pTSjbauDHpdyg5HQ26vYcNWnubg1JehmwAE9NnU9 > copy-of-tree-in-cosmos.jpg 76 | ``` 77 | 78 | ### Step 5: Examine the blocks individually 79 | 80 | Use these commands to examine the blocks in the hash tree: 81 | * `ipfs block stat` will tell you the exact size of a given block (without its 82 | children) 83 | * `ipfs refs` will tell you all the children of that block. This is a more suitable command for scripting something to run on each child block of a given object. 84 | * `ipfs ls` or `ipfs object links` will show you all children and their sizes. 85 | 86 | 87 | ### Step 6: Read the Contents of a sub-block 88 | 89 | In some cases you want to retrieve sub-blocks from a tree. You can use `ipfs cat` to do that. You can test that with the sub-bocks from our image. 90 | 91 | ```sh 92 | $ ipfs cat QmPHPs1P3JaWi53q5qqiNauPhiTqa3S1mbszcVPHKGNWRh 93 | ``` 94 | 95 | The output will look similar to this because it's image content, not text: 96 | ``` 97 | ^@^PJFIF^@^A^A^@^@^A^@^A^@^@^@;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 95 98 | ^@C^@^B^A^A^A^A^A^B^A^A^A^B^B^B^B^B^D^C^B^B^B^B^E^D^D^C^D^F^E^F^F^F^E^F^F^F^G ^F^G ^G^F^F^H^K^H 99 | 100 | 101 | ???w!1AQaq"2B???? #3R?br? 102 | $4?%?&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz?????????????????????????????????????????????????????????????????????????? 103 | ,?y?ՠ|ѿiMgᦧk?_?WN??W????F!%T 8?W???I$uZ?????K?\?olng?H|?????@?#8?En?1??; 104 | ``` 105 | 106 | ### Step 7: Assemble the Pieces Manually 107 | 108 | `ipfs cat` allows you read the contents of each block and it also allows you to _concatenate_ many inputs. This means we can use `ipfs cat` to re-build our image by passing the hashes of all our sub-blocks into that command. 109 | 110 | ```sh 111 | ipfs cat QmPHPs1P3JaWi53q5qqiNauPhiTqa3S1mbszcVPHKGNWRh QmPCuqUTNb21VDqtp5b8VsNzKEMtUsZCCVsEUBrjhERRSR QmS7zrNSHEt5GpcaKrwdbnv1nckBreUxWnLaV4qivjaNr3 QmQQhY1syuqo9Sq6wLFAupHBEeqfB8jNnzYUSgZGARJrYa > manually-rebuilt-tree-in-cosmos.jpg 112 | ``` 113 | 114 | ## Bonus Steps 115 | 116 | Some things to try: 117 | * Write a script that uses `ipfs refs` and `ipfs cat` to rebuild a file from its root hash 118 | 119 | ## Explanation 120 | 121 | Merkle DAGs are the core concept of IPFS. Merkle DAGs are also at the core of technologies like git, bitcoin and dat. 122 | 123 | Hash trees are made up of _content blocks_ that are each identified by their cryptographic hash. You can reference any of these blocks using its hash, which allows you to build trees of blocks that reference their "sub blocks" using the hashes of those sub blocks. 124 | 125 | The `ipfs add` command will create a Merkle DAG out of the data in the files you specify. It follows the unixfs data format when doing this. What this means is 126 | that your files are broken down into blocks, and then arranged in a tree-like structure using 'link nodes' to tie them together. A given file's 'hash' is actually the hash of the root (uppermost) node in the DAG. for a given DAG, you can easily view the sub-blocks under it with `ipfs ls`. 127 | 128 | ## Next Steps 129 | 130 | Next, examine [The Cryptographic Hash](/ipfs-dag/lessons/crypto-hash.md) 131 | 132 | -------------------------------------------------------------------------------- /ipfs-dag/lessons/hash-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipfs-shipyard/ipfs-primer/af7c2b9d4ef3cf8a3fadcea56acfc311591fe483/ipfs-dag/lessons/hash-tree.png -------------------------------------------------------------------------------- /publishing-changes/README.md: -------------------------------------------------------------------------------- 1 | # Tutorial: Making Changes on the Permanent Web 2 | 3 | These Lessons are tested with go-ipfs version 0.5.0. _Please update this file on github to reflect any other versions that have been tested._ 4 | 5 | ## Prerequisites 6 | 7 | ## Learning Objectives 8 | These Lessons will teach you how to 9 | * Update Files on IPFS using IPNS (InterPlanetary Name System) 10 | * Explain how version histories of files appear on IPFS 11 | * Explain why IPFS is called the Permanent Web 12 | * Track and Publish an entire website as it changes over time using IPFS and IPNS 13 | 14 | ## Key Concepts 15 | * IPNS 16 | * The Permanent Web 17 | * Using hashes to uniquely identify versions of content 18 | 19 | ## Conceptual Framework 20 | 21 | Normally, updating content means replacing a file - for instance, if I update a blog post, then people will see the new edited file, and not the old one. 22 | However, with IPFS, both versions of the file will be accessible in the network. It's not a matter of replacing: you add the new one, too. This raises the question: how do we actually update our links, so that people will see the new version of a file? They can't go to the file's location, because IPFS locates files by looking for their hashes (that's what content-addressed means). So, you need to have a way of pointing people to the new hash easily. 23 | 24 | The trick is to add new the content, and then update a pointer to that content. So, there needs to be a way of having a mutable pointer. 25 | 26 | This is where IPNS comes in, the InterPlanetary Name System. IPNS is a simple service that uses your peer ID to point to a particular hash. This hash can change, but your peer ID doesn't. That means that you can point to content in IPFS that may also change, and people can still access it without needing to know the new hash before hand. 27 | 28 | ## Lessons 29 | 30 | 1. [Lesson: Create a Simple Webpage and Add It to IPFS](/publishing-changes/lessons/create-webpage.md) 31 | 2. [Lesson: View Your Webpage with IPFS and Publish to IPNS](/publishing-changes/lessons/view-and-publish.md) 32 | 3. [Lesson: Modify Your Webpage and Republish to IPNS](/publishing-changes/lessons/modify-republish.md) 33 | 4. [Lesson: Generate and Use a New IPNS Name Keypair](/publishing-changes/lessons/generate-keypair.md) 34 | 35 | -------------------------------------------------------------------------------- /publishing-changes/lessons/create-webpage.md: -------------------------------------------------------------------------------- 1 | # Lesson: Create a Simple Webpage and Add It to IPFS 2 | 3 | This lesson shows you how to create a simple webpage and add it to IPFS. Once you are able to do this you can make your webpages as beautiful or complex as you would like, and add them to IPFS using the same basic commands. 4 | 5 | ## Prerequisites 6 | To do the steps in this lesson you must: 7 | * [Install and Initialize IPFS](/install-ipfs/README.md) on your local machine 8 | 9 | ## Goals 10 | 11 | After doing this Lesson you will be able to 12 | * Create a simple webpage and add it to IPFS 13 | 14 | ## Steps 15 | 16 | ### Step 1: Start the IPFS daemon 17 | 18 | If the IPFS daemon is not running already, then start the daemon now 19 | 20 | ```sh 21 | $ ipfs daemon 22 | ``` 23 | 24 | ### Step 2: Create webpage directory and content 25 | 26 | Create a new webpage directory in your user's home directory. 27 | 28 | ```sh 29 | $ cd ~ (or cd %userprofile% on Windows) 30 | $ mkdir simple-webpage 31 | $ cd simple-webpage/ 32 | ``` 33 | 34 | Download this nice kitten image using ipfs: 35 | ```sh 36 | $ ipfs cat QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg > cat.jpg 37 | ``` 38 | 39 | Using a text editor, create a file called `index.html` and copy/paste the following content: 40 | 41 | ```sh 42 | 43 | 44 | 45 | Nice Kitty 46 | 47 | 48 |
49 |

Nice Kitty

50 | 51 |
52 | 53 | 54 | ``` 55 | 56 | Save `index.html` in the `simple-webpage` directory and close the text editor. If you like, you may open `index.html` in the browser to see the webpage. 57 | 58 | 59 | 60 | This simple webpage only has 2 files, `index.html` and `cat.jpg`. Now you will add the `simple-webpage` directory to IPFS: 61 | 62 | ```sh 63 | $ cd .. 64 | $ ipfs add -r simple-webpage/ 65 | ``` 66 | 67 | You should see output like the following: 68 | 69 | ```sh 70 | added Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u simple-webpage/cat.jpg 71 | added QmNiBYXmgwLvT4xBiL8cX9j5H3AckiEjAnLZsoBiK6xEEr simple-webpage/index.html 72 | added QmZhCL5rkWjH4MotDxKHUDaUESEKhTxSE7Xr16zwe59sjT simple-webpage 73 | 432.98 KiB / 432.98 KiB [=============================================] 100.00% 74 | ``` 75 | 76 | Notice that you used the command `ipfs add` with the `-r` option to tell IPFS to recursively add the contents of the directory. 77 | 78 | ## Explanation 79 | 80 | You can work on a webpage locally and then add it to IPFS. When you add your webpage directory content to IPFS, you use `ipfs add` with the `-r` option to recursively add all of the files within the directory to IPFS. 81 | 82 | ## Next Steps 83 | 84 | Proceed to the next lesson to learn how to [View Your Webpage with IPFS and Publish to IPNS](/publishing-changes/lessons/view-and-publish.md) 85 | -------------------------------------------------------------------------------- /publishing-changes/lessons/generate-keypair.md: -------------------------------------------------------------------------------- 1 | # Lesson: Generate and Use a New IPNS Name Keypair 2 | 3 | This lesson shows you how to generate an new name keypair and use it to publish a different IPNS webpage than your original Peer ID. 4 | 5 | ## Goals 6 | 7 | After doing this Lesson you will be able to 8 | * Generate a new name keypair and use it along with IPNS. 9 | 10 | ## Steps 11 | 12 | ### Step 1: Generate a new name keypair 13 | 14 | Imagine that you want to create a new name keypair called "trains". Run the following command: 15 | 16 | ```sh 17 | $ ipfs key gen --type=rsa --size=2048 trains 18 | ``` 19 | 20 | Output should be a hash similar to the following: 21 | 22 | ```sh 23 | QmexZbauipkBBrV8vZv8WjeYe8F7ojCm4UZXuAhxk5vFF1 24 | ``` 25 | 26 | Now you might list the keys that you have on your local node: 27 | 28 | ```sh 29 | $ ipfs key list 30 | self 31 | trains 32 | ``` 33 | 34 | Note that "self" is the default name for the keypair of your Peer ID. This keypair is used when you `ipfs name publish` without specifying the name. 35 | 36 | ### Step 2: Create new webpage directory and content 37 | 38 | Create a new webpage directory in your user's home directory for trains. 39 | 40 | ```sh 41 | $ cd ~ (or cd %userprofile% on Windows) 42 | $ mkdir trains-webpage 43 | $ cd trains-webpage/ 44 | ``` 45 | 46 | Download 2 train images using ipfs: 47 | 48 | ``` sh 49 | $ ipfs cat QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/I/m/MNRR_maintenance_train_at_Beacon.jpg > train1.jpg 50 | $ ipfs cat QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/I/m/New_Jersey_Transit_train_53_to_Port_Jervis.jpg > train2.jpg 51 | ``` 52 | 53 | Using a text editor, create a file called `index.html` and copy/paste the following content: 54 | 55 | ```sh 56 | 57 | 58 | 59 | Trains 60 | 61 | 62 |

Trains

63 | 64 | 65 | 66 | 67 | ``` 68 | 69 | Save `index.html` in the `trains-webpage` directory and close the text editor. If you like, you may open `index.html` in the browser to see the webpage. 70 | 71 | 72 | 73 | 74 | ### Step 3: Add your webpage to IPFS and IPNS 75 | 76 | Now you can add your `trains-webpage` directory to IPFS 77 | 78 | ```sh 79 | $ cd .. 80 | $ ipfs add -r trains-webpage/ 81 | ``` 82 | 83 | You should see output like the following: 84 | 85 | ```sh 86 | added QmWq1TLwLiem1R66oDGeqgvNhVqMQp2pTH45ccMDKgqiSD trains-webpage/index.html 87 | added QmRiSPSMK1nC3adhL1N1o2CWLGve6iUMijikmsVbAh5gt4 trains-webpage/train1.jpg 88 | added QmZqx5XsHhU5qGoWXPgqa8EHRh8JRCCCQPudp1MJcVERTG trains-webpage/train2.jpg 89 | added QmTVgwpmruEWN8Dyx71FnBzymxfs8B5qV9Wuy8W4NZehPB trains-webpage 90 | 13.97 KiB / 13.97 KiB [===============================================] 100.00% 91 | ``` 92 | 93 | You now know from the earlier lessons that you can view your webpage by using the hash from the last line above (Note that your own hash may be different): 94 | 95 | `https://ipfs.io/ipfs/QmTVgwpmruEWN8Dyx71FnBzymxfs8B5qV9Wuy8W4NZehPB` 96 | 97 | Now you can publish your trains webpage to IPNS **using your new "trains" keypair** with the hash of the trains-webpage/ directory: 98 | 99 | ```sh 100 | $ ipfs name publish --key=trains QmTVgwpmruEWN8Dyx71FnBzymxfs8B5qV9Wuy8W4NZehPB 101 | ``` 102 | You should see output like the following: 103 | 104 | ```sh 105 | Published to QmexZbauipkBBrV8vZv8WjeYe8F7ojCm4UZXuAhxk5vFF1: 106 | /ipfs/QmTVgwpmruEWN8Dyx71FnBzymxfs8B5qV9Wuy8W4NZehPB 107 | ``` 108 | 109 | Note that the "Published to" hash above is the new name keypair "trains" hash that you created at the top of this page. 110 | 111 | View the new webpage using the IPNS link with your "trains" hash: 112 | 113 | `https://ipfs.io/ipns/QmexZbauipkBBrV8vZv8WjeYe8F7ojCm4UZXuAhxk5vFF1` 114 | 115 | Use the same procedure that you learned earlier to update this webpage, add to IPFS, and republish to IPNS. 116 | 117 | ## Explanation 118 | 119 | At any time you like you may generate a new name keypair to use with IPFS/IPNS work. This will allow you to work with multiple keypairs other than your primary Peer ID. 120 | 121 | ## Next Steps 122 | Next, proceed to the [Merkle Trees and the IPFS DAG](../../ipfs-dag/README.md) tutorial. 123 | -------------------------------------------------------------------------------- /publishing-changes/lessons/modify-republish.md: -------------------------------------------------------------------------------- 1 | # Lesson: Modify Your Webpage and Republish to IPNS 2 | 3 | This lesson shows you how to modify the simple webpage which you previously added to IPFS, and then how to republish that webpage to IPNS. 4 | 5 | ## Goals 6 | 7 | After doing this Lesson you will be able to 8 | * Modify any webpage that you have within IPFS and republish your new webpage to IPNS. 9 | 10 | ## Steps 11 | 12 | ### Step 1: Modify your existing webpage 13 | 14 | You will be working again in the `simple-webpage` directory: 15 | 16 | ```sh 17 | $ cd ~ (or cd %userprofile% on Windows) 18 | $ cd simple-webpage/ 19 | ``` 20 | 21 | Using the text editor, open the `index.html` file in the `simple-webpage` directory and copy/replace with the following text: 22 | 23 | ```sh 24 | 25 | 26 | 27 | Nice Kitty Update 28 | 29 | 30 |
31 |

Nice Kitty Update

32 |

This is the updated version of our Nice Kitty webpage.

33 | 34 |
35 | 36 | 37 | ``` 38 | 39 | Save `index.html` in the `simple-webpage` directory and close the text editor. 40 | 41 | Add another level of complexity with one more HTML file in the `simple-webpage` directory. Using the text editor, copy/paste the following text: 42 | 43 | ```sh 44 | 45 | 46 | 47 | 48 | SECRET 49 | 50 | 51 | This is our SECRET html file, no one will
52 | ever know that we have hidden this here! 53 | 54 | 55 | ``` 56 | 57 | Save this as `secret.html` in the `simple-webpage` directory and close the text editor. 58 | 59 | ### Step 2: Add your updated webpage to IPFS 60 | 61 | Run the following commands to update your webpage to IPFS: 62 | 63 | ```sh 64 | $ cd .. 65 | $ ipfs add -r simple-webpage/ 66 | ``` 67 | 68 | You should see output like the following: 69 | 70 | ```sh 71 | added Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u simple-webpage/cat.jpg 72 | added QmWRijdpZxJVhbUdEmvt2xD4GdCns3EVmTLBRXrJusNmGf simple-webpage/index.html 73 | added QmPx2wNJK3tT5AMPuZwjNAMUkVyR1UB8UYAxx4QmLZovtx simple-webpage/secret.html 74 | added QmXw1gREZvLbNtpEfSCA6cP8SgwhMkbPJrkC93A97uXHqf simple-webpage 75 | 433.27 KiB / 433.27 KiB [=============================================] 100.00% 76 | ``` 77 | 78 | Because the content in the `simple-webpage` directory has been changed, the final hash for the directory is now different. You might notice that the hash for `cat.jpg` has not changed, as no changes were made to that file. 79 | 80 | The IPFS hash on the last line is the hash you will use to view your webpage. Note that your own hash may be different. Use your IPFS hash and open your webpage in the browser like so: 81 | 82 | `https://ipfs.io/ipfs/your-webpage-hash` 83 | 84 | You should see the "Nice Kitty Update" webpage. Also try to access the `secret.html` webpage: 85 | 86 | `https://ipfs.io/ipfs/your-webpage-hash/secret.html` 87 | 88 | And now you can republish your updated webpage to IPNS: 89 | 90 | ```sh 91 | $ ipfs name publish your-webpage-hash 92 | ``` 93 | You should see output like the following: 94 | 95 | ```sh 96 | Published to QmRX....xQTp: (your peer id) 97 | /ipfs/QmZh....your-webpage-hash....9sjT 98 | ``` 99 | 100 | So you can see that when you republish the updated IPFS webpage to IPNS, it will again tie your Peer ID to your updates. This is the power of being able to use IPNS to point to your updated webpage. 101 | 102 | View the updated webpage using the IPNS link with your Peer ID: 103 | 104 | `https://ipfs.io/ipns/your-peer-id` 105 | 106 | and also view the `secret.html` webpage: 107 | 108 | `https://ipfs.io/ipns/your-peer-id/secret.html` 109 | 110 | ## Explanation 111 | 112 | The IPFS hash of your webpage changes every time you make a update to the webpage. By using `ipfs name publish` you can republish your webpage using IPNS, which will use the same hash every time, tied to your Peer ID. In this way you can distribute your IPNS link with your Peer ID, and anyone accessing your webpage with this link will get the most current version when you republish. 113 | 114 | ## Next Steps 115 | 116 | Proceed to the next lesson to learn how to [Generate and Use a New IPNS Name Keypair](/publishing-changes/lessons/generate-keypair.md) 117 | -------------------------------------------------------------------------------- /publishing-changes/lessons/trains.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipfs-shipyard/ipfs-primer/af7c2b9d4ef3cf8a3fadcea56acfc311591fe483/publishing-changes/lessons/trains.jpg -------------------------------------------------------------------------------- /publishing-changes/lessons/view-and-publish.md: -------------------------------------------------------------------------------- 1 | # Lesson: View Your Webpage with IPFS and Publish to IPNS 2 | 3 | This lesson shows you how to view a simple webpage which you added to IPFS, and then how to publish that webpage to IPNS. 4 | 5 | ## Goals 6 | 7 | After doing this Lesson you will be able to 8 | * View the simple webpage you created earlier and publish it to IPNS 9 | 10 | ## Steps 11 | 12 | ### Step 1: View your webpage using the IPFS hash 13 | 14 | When you ran the command `ipfs add -r simple-webpage/` in the previous lesson, your output was similar to this: 15 | 16 | ```sh 17 | added Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u simple-webpage/cat.jpg 18 | added QmNiBYXmgwLvT4xBiL8cX9j5H3AckiEjAnLZsoBiK6xEEr simple-webpage/index.html 19 | added QmZhCL5rkWjH4MotDxKHUDaUESEKhTxSE7Xr16zwe59sjT simple-webpage 20 | 432.98 KiB / 432.98 KiB [=============================================] 100.00% 21 | ``` 22 | 23 | The IPFS hash on the last line is the hash you will use to view your webpage. Note that your own hash may be different. Use your IPFS hash and open your webpage in the browser like so: 24 | 25 | `https://ipfs.io/ipfs/your-webpage-hash` 26 | 27 | You should see the "Nice Kitty" webpage from the previous lesson. 28 | 29 | ### Step 2: Publish your webpage to IPNS 30 | 31 | Wonderful, now you have your webpage available via IPFS. But suppose you have decided to make a change to this webpage? The IPFS hash above will only ever point to this first version of your webpage. By using IPNS (the InterPlanetary Name System), you can create a hash that will not change, but you will make it point to your changing content found within IPFS. The IPNS hash will be tied to your Peer ID, and any changes in the future will also be tied to your Peer ID. 32 | 33 | Run the following command (using your webpage hash) to publish to IPNS: 34 | 35 | ```sh 36 | $ ipfs name publish your-webpage-hash 37 | ``` 38 | 39 | You should see output like the following: 40 | 41 | ```sh 42 | Published to QmRX....xQTp: (your peer id) 43 | /ipfs/QmZh....your-webpage-hash....9sjT 44 | ``` 45 | 46 | Note that the hash on the first line will be your Peer ID. Using IPNS, you have tied your Peer ID to the webpage that you added to IPFS earlier. You can confirm that your Peer ID is tied to that IPFS entry with the following command: 47 | 48 | 49 | ```sh 50 | $ ipfs name resolve your-peer-id 51 | ``` 52 | You should see output like the following: 53 | 54 | ```sh 55 | /ipfs/your-webpage-hash 56 | ``` 57 | 58 | Now you will be able to view the webpage using an IPNS link with your Peer ID: 59 | 60 | `https://ipfs.io/ipns/your-peer-id` 61 | 62 | Note how the URL changes from `/ipfs/` to `/ipns/` once you publish to IPNS. 63 | 64 | ## Explanation 65 | 66 | The IPFS hash for your webpage will always point to the exact same content, this is one of the fundamental ideas of the "Permanent Web". If you make changes to your webpage, then your new IPFS content will have a different hash. If you use IPNS to tie your webpage to your Peer ID, then you can make changes to your webpage and publish your URL using the IPNS hash. 67 | 68 | ## Next Steps 69 | 70 | Proceed to the next lesson to learn how to [Modify Your Webpage and Republish to IPNS](/publishing-changes/lessons/modify-republish.md) 71 | -------------------------------------------------------------------------------- /publishing-changes/lessons/webpage4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipfs-shipyard/ipfs-primer/af7c2b9d4ef3cf8a3fadcea56acfc311591fe483/publishing-changes/lessons/webpage4.png -------------------------------------------------------------------------------- /samples/sample-text-file.txt: -------------------------------------------------------------------------------- 1 | This is some sample text. 2 | ... and a second line. 3 | -------------------------------------------------------------------------------- /samples/tree-in-cosmos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipfs-shipyard/ipfs-primer/af7c2b9d4ef3cf8a3fadcea56acfc311591fe483/samples/tree-in-cosmos.jpg -------------------------------------------------------------------------------- /styles/website.css: -------------------------------------------------------------------------------- 1 | .markdown-section pre { 2 | background: black; 3 | color: white; 4 | border: 2px solid lightgray; 5 | } 6 | .markdown-section h1, .markdown-section h2, .markdown-section h3 { 7 | font-weight: 200; 8 | } 9 | 10 | .markdown-section ol ol { 11 | margin-top: .25em; 12 | margin-bottom: .25em; 13 | } 14 | --------------------------------------------------------------------------------