IPFS Multiformats - multiaddr

multiaddr 는 자가 기술 네트워크 주소입니다. 현재 네트워크 주소 형식을 개선하는 좋은 방법이며 네트워크를 결합하여 효율적으로 사용할 수 있는 방안으로 생각할 수 있습니다.

현재 주소 지정 체계가 가지고 있는 주요 문제점은 다음과 같습니다.

  • 프로토콜 마이그레이션과 프로토콜 간의 상호 운용성을 방해합니다.
  • X-over-Y 구조 uri/url 또는 host:port 체계에서만 해결할 수 있습니다.
  • 멀티플렉싱을 지원하지 않습니다. 주소 포트가 아니라 프로세스입니다.
  • 암묵적으로 out-of-band 값과 컨텍스트를 가정합니다.
  • 기계로 읽을 수 있는 효율적인 표현을하지 못합니다.

multiaddr 는 이러한 문제를 개선하기 위해 다음 기능을 제공합니다.

  • multiaddrs 는 모든 네트워크 프로토콜의 주소를 지원합니다.
  • multiaddrs 는 자가 기술합니다.
  • multiaddrs 는 간단한 구문을 따르므로 구문 분석 및 구성이 중요하지 않습니다.
  • multiaddrs 는 사람이 읽을 수 있고 효율적인 기계 판독이 가능합니다.
  • multiaddrs 는 잘 포장되어있어 캡슐화 레이어의 간단한 패키징 및 전개가 가능합니다.

아래의 두 예를 보겠습니다.

보통 형식:

127.0.0.1:9090   # ip4. is this TCP? or UDP? or something else?
[::1]:3217       # ip6. is this TCP? or UDP? or something else?

http://127.0.0.1/baz.jpg
http://foo.com/bar/baz.jpg
//foo.com:1234
 # use DNS, to resolve to either ip4 or ip6, but definitely use
 # tcp after. or maybe quic... >.<
 # these default to TCP port :80.

multiaddr 형식:

/ip4/127.0.0.1/udp/9090/quic
/ip6/::1/tcp/3217
/ip4/127.0.0.1/tcp/80/http/baz.jpg
/dns4/foo.com/tcp/80/http/bar/baz.jpg
/dns6/foo.com/tcp/443/https

multiaddr 을 사용하면 더 명확 해지며 형식이 더 읽기 쉽습니다.

1. multiaddr 형식

Multiaddr은 재귀 TLV (Type+Length+Value) 형식으로 인코딩되며 두 형식이 있습니다.

  • 인간 친화적 버전 (UTF-8 인코딩 사용)
  • 저장 및 전송을 위한 컴퓨터 친화적 버전

인간 친화적 형식은 다음과 같이 정의됩니다.

(/<addr-protocol-str-code>/<addr-value>) +

  • 경로 기호 중첩 프로토콜 및 주소 (예 : /ip4/127.0.0.1/udp/4023/quic)
  • 유형 (addr-protocol-str-code) 은 네트워크 프로토콜을 식별하는 문자열 코드입니다. 프로토콜 테이블은 구성 가능합니다.
  • 값은 문자열 형식의 네트워크 주소 값입니다.

컴퓨터 친화적 형식은 다음과 같이 정의됩니다.

(<addr-protocol-code><addr-value>) +

  • 유형 (addr-protocol-code) 은 네트워크 프로토콜을 식별하는 변수 정수입니다. 프로토콜 테이블은 구성 가능합니다.
  • 길이는 바이트 단위의 주소 값 길이를 계산하는 데 사용되는 부호없는 변수 정수입니다.
  • 값 (addr-value) 은 네트워크 주소 길이 값입니다.

2. multiaddr 설치 및 사용

Golang 을 사용하여 multiaddr 을 사용합니다. multiaddr 설치는 다음을 통하여 설치합니다.

go get github.com/multiformats/go-multiaddr

코드:

package main

import (
    "fmt"

    ma "github.com/multiformats/go-multiaddr"
)

func main() {
    // construct from a string (err signals parse failure)
    m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
    if err != nil {
        panic(err)
    }
    // construct from bytes (err signals parse failure)
    m2, err := ma.NewMultiaddrBytes(m1.Bytes())
    if err != nil {
        panic(err)
    }

    // true
    fmt.Println(m2.Equal(m1))
    fmt.Println(m1.Protocols())
    m3, err := ma.NewMultiaddr("/sctp/5678")
    if err != nil {
        panic(err)
    }
    fmt.Println(m1.Encapsulate(m3))
    m4, err := ma.NewMultiaddr("/udp/1234")
    if err != nil {
        panic(err)
    }
    fmt.Println(m1.Decapsulate(m4))
}

설치 확인 테스트는 아래와 같이 수행합니다.

$ go run multiaddr.go
true
[{ip4 4 [4] 32 false {0x4cd930 0x4cdd00 <nil>}} {udp 273 [142 2] 16 false {0x4cdd70 0x4cdf80 <nil>}}]
/ip4/127.0.0.1/udp/1234/sctp/5678
/ip4/127.0.0.1

IPFS Multiformats - multihash

기존의 암호화 시스템에서 시스템은 항상 정보를 처리하기 위해 해시 함수 또는 암호화 함수를 잠궈야 하고 처리 된 데이터는 고정된 길이 형식입니다. 시스템의 많은 도구 또는 방법은이 암호화 시스템에 의존합니다. 이런 경우 나중에 암호화 시스템을 업그레이드하는 경우 (예: 암호화 기능 유형 교체) 전체 프로그램에 악몽같은 일이 발생합니다. 모든 관련 도구 또는 방법을 업그레이드 하여야 하며 이는 새로운 해시 함수와 새로운 해시 길이를 사용하는 것으로 심각한 상호 운용성 문제에 직면하거나 오류가 발생할 수 있습니다.

이 문제에 대한 해결책으로 Protocol Lab 은 multihash 모델을 개발했습니다.

1. multihash 형식

멀티 해시는 TLV (Type-Length-Value) 형식으로 기술됩니다.

  • hash-function-type: 서명되지 않은 varint 로 기술됩니다. 테이블을 사용하여 구성하십시오.
  • digest-length: 다이제스트의 길이는 부호없는 varints 로 계산됩니다.
  • digest-value: 다이제스트 길이를 갖는 해시 함수의 요약을 나타냅니다.

멀티 해시 예)

sha2-sha256 해시 함수를 사용하여 “hello” 문자열을 해시하고 16 진수 문자열로 출력 하는 경우 다음과 같습니다.

var a = "hello"

b := sha256.Sum256([]byte(a))
fmt.Printf("%x",b)

출력2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

그런 다음 multihash 처리 후 다음을 얻습니다.

Multihash: 12202cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

# 의미는 다음과 같습니다.
- 해시 함수: sha2-256 (0x12)
- 길이: 32 (0x20)
- 초록: 41dd7b6443542e75701aa98a0c235951a28a0d851b11564d20022ab11d2589a8

해시 함수가 sha2-512 인 경우:

Multihash : 132052eb4dd19f1ec522859e12d89706156570f8fbab1824870bc6f8c7d235eef5f4

- 해시 함수: sha2-512 (16 진수 코드: 0x13)
- 길이: 32 (16 진수: 0x20)
- 초록: 52eb4dd19f1ec522859e12d89706156570f8fbab1824870bc6f8c7d235eef5f4

2. multihash 설치 및 소스 코드

Golang 을 사용하여 multihash 를 사용합니다.

multihash 설치는 다음과 같습니다.

go get github.com/multiformats/go-multihash

코드는 다음과 같습니다.

package main

import (
    "encoding/hex"
    "fmt"

    "github.com/multiformats/go-multihash"
)

func main() {
    // 문자열을 바이트 배열로 변환
    buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
    // multihash 로 바이트 배열 인코딩
    mHashBuf, _ := multihash.EncodeName(buf, "sha1")
    // 코드화 요약 출력
    fmt.Printf("hex: %s\n", hex.EncodeToString(mHashBuf))
    // binary multihash 해시를 DecodedMultihash의 형식으로 변환
    mHash, _ := multihash.Decode(mHashBuf)
    // 디지트 된 요약 보기
    sha1hex := hex.EncodeToString(mHash.Digest)
    // 출력
    fmt.Printf("obj: %v 0x%x %d %s\n", mHash.Name, mHash.Code, mHash.Length, sha1hex)
}

설치 확인 테스트는 아래와 같이 수행합니다.

$ go run multihash.go
hex:11140beec7b5ea3f0fdbc95dodd47f3c5bc275da8a33
obj:sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

IPFS Application 계층 - Multiformats

1. Multiformats 이란 무엇인가?

Multiformats 프로젝트는 IPFS 프로토콜용으로 특별히 제작되었습니다. 프로토콜의 상호 운용성, 유연성 유지, 확장성, 업그레이드 지원 시스템을 만드는 것입니다. 현재 IPFS 및 libp2p 모듈에서 사용되는 IPFS 시스템은 주로 ID 암호화 및 데이터 자가 기술을 담당합니다. 미래의 보안 시스템을 위한 프로토콜로 자가 기술 형식 값을 강화하여 구현됩니다. 자가 기술 형식은 시스템이 공동 작업하고 업그레이드 할 수 있게 합니다.

계약의 자가 기술 측면에는 아래 조항이 있습니다:

  • 문맥으로부터 판단되는 값이 아닌 특정 값을 지정해야합니다.
  • 확장성을 증가시켜야 합니다.
  • 컴팩트해야하며 2 진 형식으로 표현 될 수 있습니다.
  • 사람이 읽을 수 있는 표현이 있어야 합니다.

2. Multiformats 구성

Multiformats 의 구성 요소는 다음과 같습니다.

  • multihash: 자가 기술 해시 값
  • multiaddr: 자가 기술 네트워크 주소
  • multibase: 자가 기술 코드 값
  • multicodec: 자가 기술 직렬화 값
  • multistream: 자가 기술 네트워크 전송 스트림
  • multigram (WIP): 자가 기술 패킷 네트워크 프로토콜

IPFS 기본 - Application 계층

IPFS의 핵심 가치는 애플리케이션에서 실행됩니다. CDN과 유사한 기능을 활용할 수 있는데 매우 낮은 비용 대역폭을 사용하여 원하는 데이터를 얻을 수 있기 때문에 전체 응용 프로그램의 효율성이 향상됩니다.

IPFS 가 기존 기술을 대체하기 위한 두 가지 사항이 있습니다. 첫째, 시스템 효율을 향상시킬 수 있고 둘째, 시스템 비용을 줄일 수 있습니다.

위 이미지의 계보는 IPFS의 주요 적용을 보여줍니다.

IPFS 팀은 빌딩 블록과 같은 전체 프로젝트를 개발하기 위한 높은 모듈 통합 방법을 개발했습니다. 프로토콜 랩 팀은 2015 년에 설립되었습니다. 17 년 동안 IPLD, LibP2P 및 Multiformats 의 3 가지 모듈이 개발되어 기본 IPFS 를 제공합니다.

Mutiformats 는 해시 암호화 알고리즘 및 자가 기술 메서드 모음으로 값 생성 방법을 알 수 있습니다. 이 스크립트에는 nodeID 를 암호화하고 기술하는 6 가지 기본 암호화 방법인 SHA1\SHA256\SHA512\Blake3B 가 있습니다.

LibP2P 는 IPFS 코어의 핵심으로 다양한 전송 계층 프로토콜과 복잡한 네트워크 장비를 사용하여 개발자가 경제적 인 P2P 네트워크 계층을 신속하게 구축 할 수 있게 해 주므로 많은 부분에서 IPFS 기술이 사용됩니다. 이는 블록 체인 프로젝트가 선호되는 이유중 하나입니다.

IPLD 는 실제로 기존의 이기종 데이터 구조를 서로 다른 시스템 간의 데이터 교환 및 상호 운용성을 용이하게하는 형식으로 통합하는 변환 미들웨어 입니다. IPLD 가 지원하는 데이터 구조는 Bitcoin 및 Ethereum 의 블록데이터이며 IPFS 및 IPLD 도 지원합니다. 이것은 IPFS 가 블록 체인 시스템에 환영받는 이유이기도 합니다. IPLD 미들웨어는 서로 다른 블록 구조를 하나의 표준으로 통합 할 수 있습니다.

IPFS 는 모든 노드가 사용할 수 있도록 별도의 노드에서 실행되는 컨테이너화 된 응용 프로그램에 통합 된 이 모듈의 기능을 웹 서비스 형태로 적용합니다.

Filecoin 은 이러한 응용 프로그램의 데이터를 중요하게 생각하여 더 많은 사람들이 노드를 만들고 더 많은 사람들이 비트 코 인과 같은 인센티브 및 경제 모델을 통해 IPFS 를 사용할 수 있게 했습니다.


IPFS 기본 - Naming 계층

1. IPNS: 네이밍 및 변수 상태

IPFS 는 해당 파일 내용을 검색 할 수 있는 파일 또는 디렉토리에 대해 주소 지정 가능한 해시 값을 생성 할 수 있습니다. 그러나 파일의 내용이 변경되면 이전 해시 값은 최신 내용을 검색 할 수 없으며 이전 내용만 검색 할 수 있습니다. 이러한 방식으로 우리가 다양한 콘텐츠를 게시 할 때 이를 검색하는 것은 매우 불편합니다.

따라서 이 문제를 해결하기 위해 IPNS 는 특정 값을 가변 컨텐츠의 최신 상태로 고정시킵니다. 즉, 파일 내용을 다시 편집 할 때 잠긴 IPNS 값으로 최신 컨텐츠에 액세스 할 수 있습니다.

2. 자가 인증 네이밍

SFS 자체 인증 네이밍 시스템은 IPFS 에 암호화 된 배포의 전역 네임 스페이스에서 가변적인 자체 인증 네이밍을 구축하는 방법을 제공합니다. IPFS 네이밍 체계는 다음과 같습니다.

  • IPFS 노드 정보는 NodeId = hash (node.PubKey) 에 의해 생성
  • 각 사용자에게는 변수 네임 스페이스가 할당되고 이전에 생성 된 노드 ID 정보가 주소 이름으로 사용 (/ipns/)
  • 사용자는 이 경로 아래에 자체 개인 키로 서명 된 객체를 게시 (/ipns/XLF2ip4ii9x0wejs23HD2swlddVmas8kd0Ax/)
  • 다른 사용자가 객체를 획득하면 서명이 공개 키 및 노드 정보와 일치하는지 여부를 검출함으로써 사용자의 공개 객체의 신뢰성을 검증하고 가변 상태 획득

예) IPNS 링크 : https://ipfs.io/ipns/QmdKXkeEWcuRw9oqBwopKUa8CgK1iBktPGYaMoJ4UNt1MP

앞 절인 https://ipfs.io/ipns/ 는 네임 스페이스이고 그 뒤에 노드의 ID 인 NodeID 가 옵니다. 모든 노드의 네임 스페이스는 IPNS 입니다.

이 블록의 동적 변화 내용은 라우팅 함수를 설정함으로 제어됩니다. 아래 소스 코드를 통해 네임 스페이스가 바운드 NodeId 의 형태로 마운트 된 이유를 알 수 있습니다: routing.setValue ( NodeId, <ns-object-hash>)

네임 스페이스에서 게시 된 데이터 객체 경로 이름은 하위 이름으로 처리 될 수 있습니다:

/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs
/ipns/XLF2ipQ4jD3UdeX5xp1KBgeHRhemUtaA8Vm/docs/ipfs

3. Human Read Naming

IPNS 는 노드의 NodeID 를 잠금 해시 값으로 사용하며 사용자는 이러한 긴 문자열을 기억하기 어렵습니다. 따라서 도메인 이름 izone.com 과 같은 정책을 통해 도메인 이름을 설정해야 합니다. ipfs.io/ipns/izone.com 을 사용하여 데이터 컨텐츠에 액세스 할 수 있습니다.

[1] peer 노드 링크

SFS (Self-Validating File System)의 디자인 개념에 따라 사용자는 다른 사용자 노드의 개체를 자신의 네임 스페이스에 직접 연결할 수 있으므로보다 신뢰할 수있는 네트워크를 만들 수 있습니다.

# Alice 가 Bob 과 링크
ipfs link //friends/bob/

# Eve 는 Alice 와 연결
ipfs link //friends/alice /

# Eve 는 Bob 에 액세스 할 수 있음
//friends/alice/friends/bob

# Verisign 인증 도메인 방문
//foo.com

[2] DNS TXT IPNS 레코드

기존 DNS 시스템에 TXT 레코드를 추가하면 도메인 이름을 통해 IPFS 네트워크의 파일 객체에 액세스 할 수 있습니다.

# DNS TXT 레코드
ipfs.benet.ai. TXT "ipfs=XLF2ip4jD3U..."
# 상징 링크로 표현
ln -s /ipns/XLF2ip4jD3U... /ipns/fs.benet.ai

# 또한 IPFS 는 다음과 같이 이진 인코딩을 읽을 수있는 파일로 변환하는 읽기 가능 식별자 인 Proquint 를 지원
# proquint 성명
/ipns/dahih-dolij-sozuk-vosah-luvar-fuluh
# 아래의 해당 양식으로 분해
/ipns/KhWwNprxYVxKqpDZ

또한 IPFS 는 짧은 주소 지정 서비스를 제공합니다. 이 서비스는 지금 볼 수있는 DNS 및 WebURL 링크와 유사합니다.

# 사용자는 아래에서 link 를 얻을 수 있음
/ipns/shorten.er/foobar

# 자신의 네임 스페이스에 적용
/ipns/XLF2ipQ4JD3Udex6xKbgeHrhemUtaA9Vm