用Go来做以太坊开发⑧Swarm存储

Swarm

Swarm是以太坊的去中心化和分布式的存储解决方案,与IPFS类似。 Swarm是一种点对点数据共享网络,其中文件通过其内容的哈希来寻址。与Bittorrent类似,可以同时从多个节点获取数据,只要单个节点承载分发数据,它就可以随处被访问。这种方法可以在不必依靠托管任何类型服务器的情况下分发数据 - 数据可访问性与位置无关。可以激励网络中的其他节点自己复制和存储数据,从而在原节点未连接到网络时避免了对托管服务的依赖。
Swarm的激励机制Swap(Swarm Accounting Protocol)是一种协议,通过该协议,Swarm网络中的个体可以跟踪传送和接收的数据块,以及由此产生相应的(微)付款。 SWAP本身可以在更广泛的背景下运行,但它通常表现为适用于点对点之间成对会计的通用微支付方案。虽然设计通用,但它的第一个用途是将带宽计算作为Swarm去中心化的点对点存储网络中数据传输的激励的一部分。

搭建 Swarm 节点

要运行swarm,首先需要安装gethbzzd,这是swarm背景进程。

go get -d github.com/ethereum/go-ethereum
go install github.com/ethereum/go-ethereum/cmd/geth
go install github.com/ethereum/go-ethereum/cmd/swarm

然后我们将生成一个新的geth帐户。

$ geth account new

Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {970ef9790b54425bea2c02e25cab01e48cf92573}

将环境变量BZZKEY导出,并设定为我们刚刚生成的geth帐户地址。

export BZZKEY=970ef9790b54425bea2c02e25cab01e48cf92573

然后使用设定的帐户运行swarm,并作为我们的swarm帐户。 默认情况下,Swarm将在端口“8500”上运行。

$ swarm --bzzaccount $BZZKEY
Unlocking swarm account 0x970EF9790B54425BEA2C02e25cAb01E48CF92573 [1/3]
Passphrase:
WARN [06-12|13:11:41] Starting Swarm service

现在swarm进程已经可以运行了,那么我们会在下个章节

完整代码

Commands

go get -d github.com/ethereum/go-ethereum
go install github.com/ethereum/go-ethereum/cmd/geth
go install github.com/ethereum/go-ethereum/cmd/swarm
geth account new
export BZZKEY=970ef9790b54425bea2c02e25cab01e48cf92573
swarm --bzzaccount $BZZKEY

上传文件到Swarm

在上个章节我们在端口“8500”上运行了一个作为背景进程的swarm节点。 接下来就导入swarm包go-ethereumswearm/api/client。 我将把包装别名为bzzclient

import (
  bzzclient "github.com/ethereum/go-ethereum/swarm/api/client"
)

调用NewClient函数向它传递swarm背景程序的url。

client := bzzclient.NewClient("http://127.0.0.1:8500")

用内容 hello world 创建示例文本文件hello.txt。 我们将会把这个文件上传到swarm。

hello world

在我们的Go应用程序中,我们将使用Swarm客户端软件包中的“Open”打开我们刚刚创建的文件。 该函数将返回一个File类型,它表示swarm清单中的文件,用于上传和下载swarm内容。

file, err := bzzclient.Open("hello.txt")
if err != nil {
  log.Fatal(err)
}

现在我们可以从客户端实例调用Upload函数,为它提供文件对象。 第二个参数是一个可选添的现有内容清单字符串,用于添加文件,否则它将为我们创建。 第三个参数是我们是否希望我们的数据被加密。

返回的哈希值是文件的内容清单的哈希值,其中包含hello.txt文件作为其唯一条目。 默认情况下,主要内容和清单都会上传。 清单确保您可以使用正确的mime类型检索文件。

manifestHash, err := client.Upload(file, "", false)
if err != nil {
    log.Fatal(err)
}

fmt.Println(manifestHash) // 2e0849490b62e706a5f1cb8e7219db7b01677f2a859bac4b5f522afd2a5f02c0

然后我们就可以在这里查看上传的文件 bzz://2e0849490b62e706a5f1cb8e7219db7b01677f2a859bac4b5f522afd2a5f02c0,具体如何下载,我们会在下个章节介绍。


完整代码

Commands

geth account new
export BZZKEY=970ef9790b54425bea2c02e25cab01e48cf92573
swarm --bzzaccount $BZZKEY

hello.txt

hello world

swarm_upload.go

package main

import (
    "fmt"
    "log"

    bzzclient "github.com/ethereum/go-ethereum/swarm/api/client"
)

func main() {
    client := bzzclient.NewClient("http://127.0.0.1:8500")

    file, err := bzzclient.Open("hello.txt")
    if err != nil {
        log.Fatal(err)
    }

    manifestHash, err := client.Upload(file, "", false)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(manifestHash) // 2e0849490b62e706a5f1cb8e7219db7b01677f2a859bac4b5f522afd2a5f02c0
}

从Swarm下载文件

在上个章节 我们将一个hello.txt文件上传到swarm,作为返回值,我们得到了一个内容清单哈希。

manifestHash := "f9192507e2e8e118bfedac428c3aa1dec4ae156e954128ec5fb27f63ee67bcac"

让我们首先通过调用“DownloadManfest”来下载它,并检查清单的内容。

manifest, isEncrypted, err := client.DownloadManifest(manifestHash)
if err != nil {
    log.Fatal(err)
}

我们可以遍历清单条目,看看内容类型,大小和内容哈希是什么。

for _, entry := range manifest.Entries {
    fmt.Println(entry.Hash)        // 42179060941352ba7b400b16c40f1e1290423a826de2a70587034dc14bc4ab2f
    fmt.Println(entry.ContentType) // text/plain; charset=utf-8
    fmt.Println(entry.Path)        // ""
}

如果您熟悉swarm url,它们的格式为bzz:/ / ,因此为了下载文件,我们指定了清单哈希和路径。 在这个例子里,路径是一个空字符串。 我们将这些数据传递给Download函数并返回一个文件对象。

file, err := client.Download(manifestHash, "")
if err != nil {
    log.Fatal(err)
}

我们现在可以阅读并打印返回的文件阅读器的内容。

content, err := ioutil.ReadAll(file)
if err != nil {
  log.Fatal(err)
}

fmt.Println(string(content)) // hello world

正如预期的那样,它记录了我们原始文件所包含的 hello world

完整代码

Commands

geth account new
export BZZKEY=970ef9790b54425bea2c02e25cab01e48cf92573
swarm --bzzaccount $BZZKEY

swarm_download.go

package main

import (
    "fmt"
    "io/ioutil"
    "log"

    bzzclient "github.com/ethereum/go-ethereum/swarm/api/client"
)

func main() {
    client := bzzclient.NewClient("http://127.0.0.1:8500")
    manifestHash := "2e0849490b62e706a5f1cb8e7219db7b01677f2a859bac4b5f522afd2a5f02c0"
    manifest, isEncrypted, err := client.DownloadManifest(manifestHash)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(isEncrypted) // false

    for _, entry := range manifest.Entries {
        fmt.Println(entry.Hash)        // 42179060941352ba7b400b16c40f1e1290423a826de2a70587034dc14bc4ab2f
        fmt.Println(entry.ContentType) // text/plain; charset=utf-8
        fmt.Println(entry.Size)        // 12
        fmt.Println(entry.Path)        // ""
    }

    file, err := client.Download(manifestHash, "")
    if err != nil {
        log.Fatal(err)
    }

    content, err := ioutil.ReadAll(file)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(content)) // hello world
}

添加小编微信:grey0805,加入知识学习小分队~!

你可能感兴趣的:(用Go来做以太坊开发⑧Swarm存储)