{"id":19865989,"url":"https://github.com/multiformats/multiaddr","last_synced_at":"2025-05-15T13:04:18.135Z","repository":{"id":17597125,"uuid":"20400820","full_name":"multiformats/multiaddr","owner":"multiformats","description":"Composable and future-proof network addresses","archived":false,"fork":false,"pushed_at":"2024-10-29T17:09:23.000Z","size":111,"stargazers_count":448,"open_issues_count":39,"forks_count":87,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-04-15T03:44:00.520Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://multiformats.io/multiaddr","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/multiformats.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-02T10:51:19.000Z","updated_at":"2025-04-07T10:16:28.000Z","dependencies_parsed_at":"2024-05-30T22:23:36.262Z","dependency_job_id":"24aebee7-0aa8-4c43-8248-ab302db73757","html_url":"https://github.com/multiformats/multiaddr","commit_stats":{"total_commits":97,"total_committers":51,"mean_commits":"1.9019607843137254","dds":0.9072164948453608,"last_synced_commit":"5a179104a6f9e9a2c95562496c88bf514871a1d3"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultiaddr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultiaddr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultiaddr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultiaddr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/multiformats","download_url":"https://codeload.github.com/multiformats/multiaddr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249003938,"owners_count":21196794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T15:24:42.326Z","updated_at":"2025-04-15T03:44:11.945Z","avatar_url":"https://github.com/multiformats.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# multiaddr\n\n[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)\n[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)\n[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)\n[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)\n\n\u003e Composable and future-proof network addresses\n\n- [Introduction](#introduction)\n- [Use cases](#use-cases)\n  - [Encapsulation based on context](#encapsulation-based-on-context)\n- [Specification](#specification)\n  - [Encoding](#encoding)\n  - [Decoding](#decoding)\n- [Protocols](#protocols)\n- [Implementations](#implementations)\n- [Contribute](#contribute)\n- [License](#license)\n\n\n## Introduction\n\nMultiaddr aims to make network addresses future-proof, composable, and efficient.\n\nCurrent addressing schemes have a number of problems.\n\n1. They hinder protocol migrations and interoperability between protocols.\n2. They don't compose well. There are plenty of X-over-Y constructions,\n   but only few of them can be addressed in a classic URI/URL or host:port scheme.\n3. They don't multiplex: they address ports, not processes.\n4. They're implicit, in that they presume out-of-band values and context.\n5. They don't have efficient machine-readable representations.\n\nMultiaddr solves these problems by modelling network addresses as arbitrary encapsulations of protocols.\n\n- Multiaddrs support addresses for any network protocol.\n- Multiaddrs are self-describing.\n- Multiaddrs conform to a simple syntax, making them trivial to parse and construct.\n- Multiaddrs have human-readable and efficient machine-readable representations.\n- Multiaddrs encapsulate well, allowing trivial wrapping and unwrapping of encapsulation layers.\n\nMultiaddr was originally [thought up by @jbenet](https://github.com/jbenet/random-ideas/issues/11).\n\n## Interpreting multiaddrs\n\nMultiaddrs are parsed from left to right, but they should be interpreted right\nto left. Each component of a multiaddr wraps all the left components in its\ncontext. For example, the multiaddr `/dns4/example.com/tcp/1234/tls/ws/tls`\n(ignore the double encryption for now) is interpreted by taking the first `tls`\ncomponent from the right and interpreting it as the libp2p security protocol to\nuse for the connection, then passing the rest of the multiaddr to the websocket\ntransport to create the websocket connection. The websocket transport sees\n`/dns4/example.com/tcp/1234/tls/ws/` and interprets the `tls` in this context to\nmean that this is going to be a secure websocket connection. The websocket\ntransport also gets the host to dial along with the tcp port from the rest of\nthe multiaddr.\n\nComponents to the right can also provide parameters to components to the left,\nsince they are in charge of the rest of the multiaddr's interpretation. For\nexample, in `/ip4/1.2.3.4/tcp/1234/tls/p2p/QmFoo` the `p2p` component has the\nvalue of the peer id and it passes it to the next component, in this case the\n`tls` security protocol, as the expected peer id for this connection. Another\nexample is `/ip4/.../p2p/QmR/p2p-circuit/p2p/QmA`, here `p2p/QmA` is passed to\n`p2p-circuit` and then the `p2p-circuit` component knows it needs to use the\nrest of the multiaddr as the information to connect to the relay node.\n\nThis enables nesting and arbitrary parameters. A component can parse\narbitrary data with some encoding and pass it as a parameter to the next\ncomponent of the multiaddr. For example, we could reference a specific HTTP path\nby composing `path` and `urlencode` components along with an `http` component.\nThis would look like\n`/dns4/example.com/http/GET/path/percentencode/somepath%2ftosomething`. The\n`percentencode` parses the data and passes it as a parameter to `path`, which\npasses it as a named parameter (`path=somepath/tosomething`) to a `GET` request. A user may not\nlike percentencode for their use case and may prefer to use `lenprefixencode` to\nhave the multiaddr instead look like\n`/dns4/example.com/http/GET/path/lenprefixencode/20_somepath/tosomething`. This\nwould work the same and require no changes to the `path` or `GET` component.\nIt's important to note that the binary representation of the data in\n`percentencode` and `lenprefixencode` would be the same. The only difference is\nhow it appears in the human-readable representation.\n\n## Use cases\n\n- TODO: unpack the shortcomings of URLs\n  - example: hostnames in https://\n    - can't sidestep DNS\n    - can't use different SNI vs. Host headers\n    - can't do http-over-utp\n    - TODO check out how http/1.1 vs. http/2 is distinguished\n  - rift between filesystem, web, and databases\n\n- TODO: case study: domain fronting\n- TODO: case study: tunnelling\n- TODO: case study: http proxying\n- TODO: case study: multi-hop circuit relay\n- TODO: case study: protocol migrations (e.g. ip4/ip6, 4in6, 6in4)\n\n\n### Encapsulation based on context\n\nAlthough multiaddrs are self-describing, it's possible to further encapsulate them based on context.\nFor example in a web browser, it's obvious that, given a hostname, HTTP should be spoken.\nThe specifics of this HTTP connection are not important (except maybe the use of TLS),\nand will be derived from the browser's capabilities and configuration.\n\n1. example.com/index.html\n2. /http/example.com/index.html\n3. /tls/sni/example.com/http/example.com/index.html\n4. /dns4/example.com/tcp/443/tls/sni/example.com/http/example.com/index.html\n5. /ip4/1.2.3.4/tcp/443/tls/sni/example.com/http/example.com/index.html\n\nThe resulting layers of encapsulation reflect exactly\nhow the bidirectional stream between client and server is constructed.\n\nNow you can imagine how based on the browser's configuration, the multiaddr might look different.\nFor example you could use HTTP proxying or SOCKS proxying, or use domain fronting to evade censorship.\nThis kind of proxying is of course possible without multiaddr,\nbut only with multiaddr do we have a way of consistently addressing these networking constructions.\n\n\n## Specification\n\n- Human-readable multiaddr: `(/\u003cprotoName string\u003e/\u003cvalue string\u003e)+`\n  - Example: `/ip4/127.0.0.1/udp/1234`\n- Machine-readable multiaddr: `(\u003cprotoCode uvarint\u003e\u003cvalue []byte\u003e)+`\n  - Same example: `0x4 0x7f 0x0 0x0 0x1 0x91 0x2 0x4 0xd2`\n  - Values are usually length-prefixed with a uvarint\n\nMultiaddr and all other multiformats use unsigned varints (uvarint).\nRead more about it in [multiformats/unsigned-varint](https://github.com/multiformats/unsigned-varint).\n\n\n### Encoding\n\nTODO: specify the encoding (byte-array to string) procedure\n\n### Decoding\n\nTODO: specify the decoding (string to byte-array) procedure\n\n\n## Protocols\n\nSee [protocols.csv](protocols.csv) for a list of protocol codes and names,\nand [protocols/](protocols/) for specifications of the currently supported protocols.\n\nTODO: most of these are way underspecified\n\n- /ip4, /ip6\n- /ipcidr\n- /dns4, /dns6\n- [/dnsaddr](protocols/DNSADDR.md)\n- /tcp\n- /udp\n- /utp\n- /tls\n- /ws, /wss\n- /ipfs\n- /p2p-circuit\n- /p2p-webrtc-star, /p2p-webrtc-direct\n- /p2p-websocket-star\n- /onion\n\n\n## Implementations\n\n- [js-multiaddr](https://github.com/multiformats/js-multiaddr) - stable\n- [go-multiaddr](https://github.com/multiformats/go-multiaddr) - stable\n  - [go-multiaddr-dns](https://github.com/multiformats/go-multiaddr-dns)\n- [java-multiaddr](https://github.com/multiformats/java-multiaddr) - stable\n- [haskell-multiaddr](https://github.com/MatrixAI/haskell-multiaddr) - stable\n- [py-multiaddr](https://github.com/multiformats/py-multiaddr) - stable\n- [rust-multiaddr](https://github.com/multiformats/rust-multiaddr) - stable\n- [cs-multiaddress](https://github.com/multiformats/cs-multiaddress) - alpha\n- [net-ipfs-core](https://github.com/richardschneider/net-ipfs-core) - stable\n- [swift-multiaddr](https://github.com/lukereichold/swift-multiaddr) - stable\n- [elixir-multiaddr](https://github.com/aratz-lasa/ex_multiaddr) - alpha\n- `multiaddr` sub-module of Python module [multiformats](https://github.com/hashberg-io/multiformats) - alpha\n- [dart-multiaddr](https://github.com/YogiLiu/dart_multiaddr) - alpha\n- Kotlin\n  - [kotlin-multiaddr](https://github.com/changjiashuai/kotlin-multiaddr) - stable\n  - `multiaddr` part of Kotlin project [multiformat](https://github.com/erwin-kok/multiformat) - alpha\n\nTODO: reconsider these alpha/beta/stable labels\n\n\n## Contribute\n\nContributions welcome. Please check out [the issues](https://github.com/multiformats/multiaddr/issues).\n\nCheck out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).\n\nSmall note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.\n\n\n## License\n\nThis repository is only for documents. All of these are licensed under the [CC-BY-SA 3.0](https://ipfs.io/ipfs/QmVreNvKsQmQZ83T86cWSjPu2vR3yZHGPm5jnxFuunEB9u) license, © 2016 Protocol Labs Inc. Any code is under a [MIT](LICENSE) © 2016 Protocol Labs Inc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiformats%2Fmultiaddr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmultiformats%2Fmultiaddr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiformats%2Fmultiaddr/lists"}