使用IBM Blockchain Platform extension開發你的第一個fabric智能合約

使用IBM Blockchain Platform extension開發你的第一個fabric智能合約docker

IBM Blockchain Platform extension是VSCode的一個插件,最新版本是v1.0.17。 typescript

該擴展支持Hyperledger Fabric和IBM Blockchain Platform的完整開發工做流程:npm

  • 生成,編輯和打包智能合約
  • 使用簡單的預先配置的本地結構網絡在本地部署和調試合同
  • 鏈接到任何Fabric環境進行部署,包括IBM Blockchain Platform服務(在IBM Cloud上)或軟件(本地和多雲)
  • 提交和評估交易,並開發客戶應用程序

這個可謂是開發Fabric智能合約的神器,比以前的本地的本身搭環境不知道好哪去了。編程

那麼有些小夥伴要問了,既然有這麼好用的神器,有沒有簡單的介紹教程呢? api

別急,下面就是。數組

安裝IBM Blockchain Platform extension for VS Code

IBM Blockchain Platform extension是工做在VS Code上面的,VS Code是微軟開源的編輯工具,也是一個很是好用的開發工具。網絡

若是你已經有了VS Code,點擊屏幕左側邊欄中的擴展程序。 在頂部,在擴展市場中搜索IBM Blockchain Platform。 單擊安裝,而後單擊從新加載。那麼就安裝好了。框架

注意事項:

Fabric是在docker環境中運行的,智能合約如今能夠用JavaScript, TypeScript, Java, Go 這四種語言來編寫。因此你須要以下的環境:async

VS Code version 1.32 or greater
Node v8.x or greater and npm v5.x or greater
Docker version v17.06.2-ce or greater
Docker Compose v1.14.0 or greater編程語言

建立一個智能合約項目

IBM Blockchain Platform extension可使用你選擇的Hyperledger Fabric支持的編程語言生成智能合約框架。裏面已經包含了簡單有用的智能合約。

在本例中,咱們將使用TypeScript做爲例子。

在左側邊欄中,單擊IBM Blockchain Platform圖標(它看起來像一個正方形,若是這是你安裝的最新擴展,則可能位於圖標集的底部)。

將鼠標懸停在SMART CONTRACT PACKAGES面板上,單擊「…」菜單,而後從下拉列表中選擇「建立智能合約項目」。

選擇一種智能合約語言。 JavaScript,TypeScript,Java和Go均可用。就本教程而言,請選擇TypeScript。

而後會詢問你是否要在生成的合同中命名資產(默認是「 MyAsset」),固然你能夠修改爲本身想要的資產名字。

選擇一個位置來保存項目。單擊瀏覽,而後單擊新建文件夾,而後根據須要命名項目(例如,「 blockchainExtProject」)。

單擊建立,而後選擇剛建立的新文件夾,而後單擊保存。

最後,從選項列表中選擇「添加到工做區」。

該擴展程序將根據你選擇的語言和資產名稱生成一個框架合同。完成後,你能夠導航到「資源管理器」視圖(最有可能在左側欄中的頂部圖標,看起來像「文檔」圖標)並打開src / my-asset-contract.ts文件以查看你的智能合約代碼腳手架。

生成的文件應該以下圖所示:

接下來,咱們將看一下生成的智能合約究竟是作什麼的。

理解智能合約

生成的智能合約代碼支架提供了一些常見的操做示例,可用於與區塊鏈分類帳上的數據進行交互。 其中my-asset-contract.ts就是生成的智能合約代碼。

/*
 * SPDX-License-Identifier: Apache-2.0
 */

import { Context, Contract, Info, Returns, Transaction } from 'fabric-contract-api';
import { MyAsset } from './my-asset';

@Info({title: 'MyAssetContract', description: 'My Smart Contract' })
export class MyAssetContract extends Contract {

    @Transaction(false)
    @Returns('boolean')
    public async myAssetExists(ctx: Context, myAssetId: string): Promise<boolean> {
        const buffer = await ctx.stub.getState(myAssetId);
        return (!!buffer && buffer.length > 0);
    }

    @Transaction()
    public async createMyAsset(ctx: Context, myAssetId: string, value: string): Promise<void> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (exists) {
            throw new Error(`The my asset ${myAssetId} already exists`);
        }
        const myAsset = new MyAsset();
        myAsset.value = value;
        const buffer = Buffer.from(JSON.stringify(myAsset));
        await ctx.stub.putState(myAssetId, buffer);
    }

    @Transaction(false)
    @Returns('MyAsset')
    public async readMyAsset(ctx: Context, myAssetId: string): Promise<MyAsset> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (!exists) {
            throw new Error(`The my asset ${myAssetId} does not exist`);
        }
        const buffer = await ctx.stub.getState(myAssetId);
        const myAsset = JSON.parse(buffer.toString()) as MyAsset;
        return myAsset;
    }

    @Transaction()
    public async updateMyAsset(ctx: Context, myAssetId: string, newValue: string): Promise<void> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (!exists) {
            throw new Error(`The my asset ${myAssetId} does not exist`);
        }
        const myAsset = new MyAsset();
        myAsset.value = newValue;
        const buffer = Buffer.from(JSON.stringify(myAsset));
        await ctx.stub.putState(myAssetId, buffer);
    }

    @Transaction()
    public async deleteMyAsset(ctx: Context, myAssetId: string): Promise<void> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (!exists) {
            throw new Error(`The my asset ${myAssetId} does not exist`);
        }
        await ctx.stub.deleteState(myAssetId);
    }

}

請注意以@Transaction開頭的行:這些是定義合同交易的函數-這些東西使你能夠與分類帳進行交互。

咱們先看看createMyAsset函數:

@Transaction()
    public async createMyAsset(ctx: Context, myAssetId: string, value: string): Promise<void> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (exists) {
            throw new Error(`The my asset ${myAssetId} already exists`);
        }
        const myAsset = new MyAsset();
        myAsset.value = value;
        const buffer = Buffer.from(JSON.stringify(myAsset));
        await ctx.stub.putState(myAssetId, buffer);
    }

@Transaction()中的括號告訴你此函數會修改分類賬的內容。

該函數稱爲createMyAsset,它接受myAssetId和一個值,二者均爲字符串。 提交此事務後,將使用關鍵字myAssetId和值建立一個新資產。 例如,假設你要建立「 001」,「my first asset」; 而後稍後,當你讀取鍵001的值時,你會知道該特定狀態的值是「my first asset」。

如今,看看下一個事務:

@Transaction(false)
    @Returns('MyAsset')
    public async readMyAsset(ctx: Context, myAssetId: string): Promise<MyAsset> {
        const exists = await this.myAssetExists(ctx, myAssetId);
        if (!exists) {
            throw new Error(`The my asset ${myAssetId} does not exist`);
        }
        const buffer = await ctx.stub.getState(myAssetId);
        const myAsset = JSON.parse(buffer.toString()) as MyAsset;
        return myAsset;
    }

這個以@Transaction(false)開頭-「 false」表示此函數一般不打算更改分類賬的內容。 這樣的事務,稱爲「查詢」。如你所見,此函數僅採用myAssetId並返回鍵所指向的任何狀態的值。

能夠詳細看下合同中的其餘交易。 而後,你能夠繼續打包和部署該合同,從而來使用它。

打包智能合約

如今,你已經建立了智能合約並瞭解其中的交易,是時候打包了。智能合約項目打包成.CDS文件,這是一種特殊類型的文件,能夠安裝在Hyperledger Fabric節點上。

在左側邊欄中,單擊IBM Blockchain Platform圖標。

將鼠標懸停在SMART CONTRACT PACKAGES面板上,單擊「…」菜單,而後從下拉列表中選擇「打包智能合約項目」。

若是一切順利,你應該在列表中看到一個新程序包blockchainExtProject@0.0.1。

你剛建立的程序包能夠安裝到任何Hyperledger Fabric peer上(以正確的版本運行)。例如,你能夠右鍵單擊並選擇「導出包」,而後使用IBM Blockchain Platform操做工具控制檯將其部署到雲環境中。如今,你將在VS Code擴展程序預配置的運行時本地部署程序包,所以如今無需導出程序包!

Local Fabric Ops

名爲LOCAL FABRIC OPS的面板(在IBM Blockchain Platform視圖中)使你能夠在本地計算機上使用Docker操做簡單的Hyperledger Fabric runtime。 最開始的時候Fabric應該是中止的:

Local Fabric runtime is stopped. Click to start.

單擊該消息,擴展將開始爲你擴展Docker容器。而後,你應該會看到消息「 Local Fabric運行時正在開始……」,當任務完成時,你將看到一組可擴展/可摺疊部分,分別標記爲「智能合約」,「通道」,「節點」和「組織。」

下面是他們的簡單描述:

  • 「智能合約」部分向你顯示此網絡上的實例化和已安裝合約。本教程的接下來的兩個步驟將向你展現如何安裝並實例化打包的智能合約。
  • 在通道下有一個稱爲「 mychannel」的通道。爲了使用智能合約,必須在一個通道上實例化它。
  • 「節點」部分包含一個對等節點(peer0.org1.example.com)。命名遵循Hyperledger Fabric約定,你能夠從「 org1」部分看到此peer歸Org1全部。
  • 還有一個證書頒發機構(CA)ca.org1.example.com和一個order節點orderer.example.com。
  • 在這個簡單的區塊鏈網絡中只有一個組織稱爲「 Org1」。只有一個組織的網絡在現實世界中使用並非很現實,由於重點是要在多個組織之間共享一個分類賬,但對於本地開發目的來講已經足夠了。在「組織」下,你將看到Org1MSP:這是Org1的MSP ID。

如今,你已經啓動了本地Fabric運行時,如今該安裝並實例化智能合約了……

安裝智能合約

在真實的網絡中,每一個將支持交易的組織都將在其peer節點上安裝智能合約,而後在通道上實例化該合約。 如今本地Fabric運行時只有一個組織(Org1),一個同級(peer0.org1.example.com)和一個通道(mychannel)。

所以,你只須要在該單個peer上安裝合同,而後即可以在mychannel中實例化該合同。 方法以下:

  1. 在「本地FABRIC OPS」面板中,找到「 +安裝」(在「智能合約」>「已安裝」下),而後單擊它。
  2. 系統會要求你選擇一個節點。 選擇惟一的選項peer0.org1.example.com。
  3. 而後,系統會要求你選擇要安裝的軟件包。 blockchainExtProject@0.0.1。

你應該看到blockchainExtProject@0.0.1出如今智能合約>已安裝列表下。

接下來,你將實例化智能合約…

實例化智能合約

在「本地FABRIC OPS」面板中,查找+實例化(在「智能合約」>「實例化」下),而後單擊它。

系統會要求你選擇一個channel。選擇惟一的選項,mychannel。

而後,系統會要求你選擇一個智能合約進行實例化。選擇blockchainExtProject@0.0.1。

而後,系統將詢問你要調用的函數。若是要在實例化過程當中使用特定功能,則能夠在此處輸入內容。如今只需按Enter便可跳過此步驟。

而後,系統會詢問你是否要提供私有數據配置文件。對於本教程,只需單擊「否」.

實例化可能比安裝花費更長的時間-請注意成功消息,並在「智能合約」>「實例化」列表中顯示blockchainExtProject@0.0.1,以確認它是否有效!

如今你的界面應該是這樣的:

提交和查詢事務

Fabric網關和Hyperledger Fabric網絡的peer進行鏈接,客戶端應用程序可使用該網關提交事務。當你在LOCAL FABRIC OPS中啓動本地實例時,也會自動爲你建立一個網關。你能夠在FABRIC GATEWAYS下找到它,它稱爲「 local_fabric」。

要使用網關,你還須要用於在該網絡上進行交易的身份。一樣,對於本地Fabric運行時,已經爲你設置了此時間。請注意,在FABRIC WALLETS下有一個名爲local_fabric_wallet的錢包,其中包含一個名爲admin的ID。若是將鼠標懸停在「 FABRIC GATEWAYS」面板中的「 local_fabric」上,你會看到它告訴你「關聯的錢包:local_fabric_wallet」。

所以,你已經有了一個網關和一個帶有單個身份的關聯錢包,這意味着該網關可使用了。

單擊local_fabric(在FABRIC GATEWAYS下)以經過此網關鏈接。

展開channel,而後展開mychannel和blockchainExtProject@0.0.1。你將看到智能合約中定義的全部交易的列表。

如今你須要建立資產。右鍵單擊createMyAsset,而後選擇Submit Transaction。系統將要求你提供交易參數:嘗試[「 001」,「my asset one」](或你喜歡的任何鍵和值,但請確保記住使用的鍵!)。

參數以JSON格式提交,所以請確保你徹底按照顯示的方式輸入輸入內容,以便你根據此交易要求提交由2個字符串組成的數組。

接下來,以相似方式提交updateMyAsset。此次,爲參數提供相同的鍵和不一樣的值,例如[「 001」,「my asset two」]。所以,如今分類賬中的鍵001的值應該是「my asset two」。讓咱們來檢查一下……

readMyAsset用於讀取而不是寫入分類賬,所以此次選擇查詢交易。輸入[「 001」](或任何你設置的鍵)做爲參數。你應該在輸出控制檯中看到如下內容:

[SUCCESS] Returned value from readMyAsset: {"value":"my asset two"}

恭喜你,你已經完成了第一個智能合約!

更多教程請參考 flydean的博客

相關文章
相關標籤/搜索