回顾 | 使用 Starport 工具 5 分钟搭建区块链

10 月 16 日,HackAtom V 正式启动,为帮助开发者更好理解并参与活动,Cosmos 举办了多场不同主题的直播活动。面向中国技术社区,IRISnet 的核心开发霍达进行了一场主题为《使用 Starport 工具,5 分钟搭建区块链》的中文直播活动。

视频回顾:

Starport 是一个开源且能快速开发原型的工具,开发人员只需使用两个 CLI 命令就可以快速构建新的区块链。目前,即使是经验丰富的区块链开发人员,构建一个新的区块链并启动本地测试网也要占用近一天的时间。而通过 Starport,开发人员可以在不到五分钟的时间内启动一个基于 Cosmos SDK 的简单区块链。Starport 的智能搭建功能从根本上减少了开发时间,并大大降低了数百万开发人员进入区块链行业的门槛。

IRISnet 核心开发霍达以文件存在证明(PoFE)为例,讲解了如何使用 Starport 工具快速进行区块链搭建和应用开发。

Demo 应用:文件存在证明(PoFE)

文件存在证明 可以帮助证明特定文件在特定时间的真实性。

如何创建文件存在证明?

创建文件存在证明可以通过对要证明存在的文件或文档执行 SHA256 哈希来完成。我们可以假设 SHA256 哈希函数的输出对于每个输入都是唯一的,并且不会发生冲突。

文件的 SHA256 哈希也称为校验和。将校验和上传到区块链时,我们创建带时间戳的证明,表明我们知道其哈希内容等于校验和值的文件。这样,我们可以在证明文件存在和所有权的同时将文件内容保密。

PoFE 用例

  • 带有时间戳记的文档您可以获取任何文档,然后将哈希值提交为区块链上的文件存在证明。这样,您可以通过共享文件并让其他人计算校验和来证明您在提交块时拥有文件。之后,可以共享指向包含该哈希的交易的链接,从而证明在执行事务时文件的存在。
  • 文件完整性政府或组织可以发布数字法律文件并为哈希加总以作为区块链上文件存在的证明。这样,可以在需要时以数字方式提交文档,任何实体都可以通过在区块链上查询其哈希值来验证其真实性。

应用概述

我们的应用程序相对简单 - 我们想要实现一个区块链,用户可以选择一个文件,对其内容进行哈希处理,然后将文件直接上传到区块链。我们还希望赋予所有者撤回的能力。

准备

Starport 是用于搭建自定义区块链的工具。

首先我们需要 安装 starport , 通过 npm , brew , 或通过源码:

npm install -g @tendermint/starport

brew install tendermint/tap/starport

git clone https://github.com/tendermint/starport && cd starport && make

现在我们可以开始构建应用了!

通过 Starport 构建 PoFE 区块链

我们可以通过运行 starport app github.com/user/pofe 来搭建我们的应用程序。这将创建一个名为 pofe 的新文件夹,其中包含应用程序的代码。

starport app github.com/user/pofe

运行

搭建好我们的应用程序后,让我们在新创建的 pofe 文件夹中打开一个单独的终端窗口,然后运行 starport serve 即可启动我们的应用程序。在这里,您应该能够看到以下输出以及应用程序中显示的所有错误。

$ starport serve
Cosmos’ version is: Launchpad

:package: Installing dependencies…
:hammer_and_wrench: Building the app…
:slightly_smiling_face: Created an account. Password (mnemonic): joy manage firm arrange finish bounce power shove bring bundle issue chief quiz spread symptom sword slender vote hobby water weird trim panther slot
:slightly_smiling_face: Created an account. Password (mnemonic): meat skirt slab smart impulse region clump genuine zero clog version father spray midnight tip poem input fantasy decide buddy work strategy nest shaft
:earth_africa: Running a Cosmos ‘pofe’ app with Tendermint at http://localhost:26657.
:earth_africa: Running a server at http://localhost:1317 (LCD)

:rocket: Get started: http://localhost:12345/

创建 Claim 类型

切换回目录 pofe 内的终端,并创建一个名为 claim 的类型,并带有 proof 字段:

starport type claim proof:string

这将创建 claim 类型,并添加其相关的 CLI 命令,处理程序,消息,类型,查询器和保持器。

至此,我们有了一个可以使用的应用程序 - 您可以通过检查辅助终端窗口的输出来验证这一点。

但是,我们想修改我们的应用程序,使其更适合我们的要求。

修改应用

我们希望实现一个接口,该接口允许某人哈希文件并将哈希提交到区块链,而无需直接上传其内容。我们将通过 ./x/pofe/client/cli/txClaim.go 中的命令来实现。

package cli

import (
“bufio”
“crypto/sha256”
“encoding/hex”
“io/ioutil”

github.com/spf13/cobra

github.com/cosmos/cosmos-sdk/client/context
github.com/cosmos/cosmos-sdk/codec
sdk “github.com/cosmos/cosmos-sdk/types
github.com/cosmos/cosmos-sdk/x/auth
github.com/cosmos/cosmos-sdk/x/auth/client/utils
github.com/lukitsbrian/poe/x/pofe/types
)

func GetCmdCreateClaim(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: “create-claim [path]”,
Short: “Creates a new claim”,
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// accept a filepath
hasher := sha256.New()
s, _ := ioutil.ReadFile(args[0])
hasher.Write(s)
argsProof := hex.EncodeToString(hasher.Sum(nil))

       cliCtx := context.NewCLIContext().WithCodec(cdc)
       inBuf := bufio.NewReader(cmd.InOrStdin())
       txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
       msg := types.NewMsgCreateClaim(cliCtx.GetFromAddress(), string(argsProof))
       err := msg.ValidateBasic()
       if err != nil {
           return err
      }
       return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
  },

}
}

最后,我们将使用结构中的 Proof 值,而不是使用自动生成的 uuid ID 作为键。这将使查询数据库中出现的 证明 变得容易得多。我们可以通过修改 ./x/pofe/keeper/claim.go 文件中的 CreateClaim 方法以及所有其他使用 claim.ID 的相关文件,用 claim.Proof 代替 claim.ID

func (k Keeper) CreateClaim(ctx sdk.Context, claim types.Claim) {
store := ctx.KVStore(k.storeKey)
key := []byte(types.ClaimPrefix + claim.Proof)
value := k.cdc.MustMarshalBinaryLengthPrefixed(claim)
store.Set(key, value)
}

根据我们的应用程序设计,我们只需要 Creator 和文件 Proof 的哈希。出于本教程的考虑,我们可以在结构中保留 ID 的实例。

但是,如果您希望清理结构和方法,一种增量方式是从 ../x/pofe/types/TypeClaim.go 文件中的 Claim 结构中删除 ID 字段。因此看起来如下:

type Claim struct {
Creator sdk.AccAddress json:"creator" yaml:"creator"
Proof string json:"proof" yaml:"proof"
}

在第二个窗口中,您应该会看到错误弹出窗口,您可以根据显示的错误逐步更改错误。

提交文件存在证明声明

错误修复之后,我们就可以开始在我们的区块链上提交 Claim!

让我们从最简单的一个开始 - 假设我们想证明我们制造了这个区块链。

当我们运行 starport serve 时,我们还将应用程序构建为名为 pofed 的二进制文件,因此我们可以使用此文件来提交 claim。

pofecli tx pofe create-claim $(which pofed) --from user1

确认交易后,运行 pofecli q pofe list-claim ,您将看到如下输出:

[
{
“creator”: “cosmos165hphx98d767c99gtm0n7gevq2q0nwrg75pfkd”,
“proof”: “534f056e58115dd106d026e00da22a32f8c776a0cd5b3dd6431598d73b5f623c”
}
]

恭喜你!您的 claim 现在在区块链上,证明您已构建此应用程序!

如果您要删除或删除 claim,只需运行以下命令:

pofecli tx pofe delete-claim 534f056e58115dd106d026e00da22a32f8c776a0cd5b3dd6431598d73b5f623c --from user1

开发前端应用

至此,我们有了一个运行良好的区块链。现在,我们可以添加一个UI,以从浏览器上传文件哈希。

首先,从导航到托管我们的 vue 应用程序的 localhost:8080 开始。

创建一个新的 Component

为了使用户更轻松地将哈希值上传到区块链,我们将创建一个新组件,该组件允许某人将文件拖放到 UI 中。该组件将计算文件哈希,用户将可以选择上传此证明作为声明。

我们可以创建一个名为 vue/src/components/DropZone.vue 的新文件夹和文件,并将新组件添加到我们的 vue/src/views/Index.vue 文件中:

DropZone.vue

Index.vue

现在,每当向组件中添加某些内容时,我们都应该看到 UI 更新。

组件布局

接下来,让我们添加一些元素来创建组件的布局。我们将重用 @tendermint/vue 组件库中的一些组件,并创建我们自己的 drop zone。

Calculate Proof
{{ hashed || placeholderText }}
Submit Proof as a new Claim
#drop-zone { font-family: "Inter", "Helvetica", sans-serif; height: 20rem; line-height: 20rem; font-size: 1.25rem; background-color: rgb(247, 247, 247); justify-content: center; text-align: center; vertical-align: middle; margin-bottom: 2rem; border-radius: 0.5rem; }

实现我们的哈希功能

如前所述,我们希望能够将文件上传到浏览器,计算其哈希值,然后将哈希值提交给区块链。

首先,我们将添加 js-sha256 包。通过 npm 安装,并确保在运行以下命令时我们位于 vue/ 目录中。

npm install --save js-sha256

一旦安装完成,我们可以添加用于创建哈希的功能:

import { sha256 } from “js-sha256”;


methods: {
hash(e) {
const files = e.dataTransfer.items;
if (!files.length) return;
// Read the file and hash it
const reader = new FileReader();
reader.onload = (ev) => {
this.hashed = sha256(ev.target.result);
};
reader.readAsArrayBuffer(files[0].getAsFile());
},

现在,我们可以添加 提交 功能,该功能会将动作分派到 cosmos 商店,以便从我们的区块链提交和获取内容。

async submit() {
// Submit
this.flight = true;
await this.$store.dispatch(“cosmos/entitySubmit”, {
type: “claim”,
body: {
proof: this.hashed,
},
});
await this.$store.dispatch(“cosmos/entityFetch”, {
type: “claim”,
});

 // Clear fields
 this.flight = false;
 this.hashed = "";
 document.getElementById("file").value = "";

},

恭喜,您的应用已完成!