使用IBM Blockchain Platform extension開發你的第一個fabric智能合約
IBM Blockchain Platform extension是VSCode的一個插件,最新版本是v1.0.17。
該擴展支持Hyperledger Fabric和IBM Blockchain Platform的完整開發工作流程:
- 生成,編輯和打包智能合約
- 使用簡單的預先配置的本地結構網絡在本地部署和調試合同
- 連接到任何Fabric環境進行部署,包括IBM Blockchain Platform服務(在IBM Cloud上)或軟件(本地和多雲)
- 提交和評估交易,並開發客戶應用程序
這個可謂是開發Fabric智能合約的神器,比之前的本地的自己搭環境不知道好哪去了。
那麼有些小夥伴要問了,既然有這麼好用的神器,有沒有簡單的介紹教程呢?
別急,下面就是。
安裝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 這四種語言來編寫。所以你需要如下的環境:
VS Code version 1.32 or greaterNode v8.x or greater and npm v5.x or greaterDocker version v17.06.2-ce or greaterDocker 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就是生成的智能合約代碼。
<code>/*
* 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);
}
}
/<void>/<void>/<myasset>/<void>/<boolean>/<code>
請注意以@Transaction開頭的行:這些是定義合同交易的函數-這些東西使你可以與分類賬進行交互。
我們先看看createMyAsset函數:
<code> @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);
}
/<void>/<code>
@Transaction()中的括號告訴你此函數會修改分類帳的內容。
該函數稱為createMyAsset,它接受myAssetId和一個值,兩者均為字符串。 提交此事務後,將使用關鍵字myAssetId和值創建一個新資產。 例如,假設你要創建“ 001”,“my first asset”; 然後稍後,當你讀取鍵001的值時,你會知道該特定狀態的值是“my first asset”。
現在,看看下一個事務:
<code> @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;
}
/<myasset>/<code>
這個以@Transaction(false)開頭-“ false”表示此函數通常不打算更改分類帳的內容。 這樣的事務,稱為“查詢”。如你所見,此函數僅採用myAssetId並返回鍵所指向的任何狀態的值。
可以詳細看下合同中的其他交易。 然後,你可以繼續打包和部署該合同,從而來使用它。
打包智能合約
現在,你已經創建了智能合約並瞭解其中的交易,是時候打包了。智能合約項目打包成.CDS文件,這是一種特殊類型的文件,可以安裝在Hyperledger Fabric節點上。
在左側邊欄中,單擊IBM Blockchain Platform圖標。
將鼠標懸停在SMART CONTRACT PACKAGES面板上,單擊“…”菜單,然後從下拉列表中選擇“打包智能合約項目”。
如果一切順利,你應該在列表中看到一個新程序包[email protected]。
你剛創建的程序包可以安裝到任何Hyperledger Fabric peer上(以正確的版本運行)。例如,你可以右鍵單擊並選擇“導出包”,然後使用IBM Blockchain Platform操作工具控制檯將其部署到雲環境中。現在,你將在VS Code擴展程序預配置的運行時本地部署程序包,因此現在無需導出程序包!
Local Fabric Ops
名為LOCAL FABRIC OPS的面板(在IBM Blockchain Platform視圖中)使你可以在本地計算機上使用Docker操作簡單的Hyperledger Fabric runtime。 最開始的時候Fabric應該是停止的:
<code>Local Fabric runtime is stopped. Click to start.
/<code>
單擊該消息,擴展將開始為你擴展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中實例化該合同。 方法如下:
- 在“本地FABRIC OPS”面板中,找到“ +安裝”(在“智能合約”>“已安裝”下),然後單擊它。
- 系統會要求你選擇一個節點。 選擇唯一的選項peer0.org1.example.com。
- 然後,系統會要求你選擇要安裝的軟件包。 [email protected]。
你應該看到[email protected]出現在智能合約>已安裝列表下。
接下來,你將實例化智能合約…
實例化智能合約
在“本地FABRIC OPS”面板中,查找+實例化(在“智能合約”>“實例化”下),然後單擊它。
系統會要求你選擇一個channel。選擇唯一的選項,mychannel。
然後,系統會要求你選擇一個智能合約進行實例化。選擇[email protected]。
然後,系統將詢問你要調用的函數。如果要在實例化過程中使用特定功能,則可以在此處輸入內容。現在只需按Enter即可跳過此步驟。
然後,系統會詢問你是否要提供私有數據配置文件。對於本教程,只需單擊“否”.
實例化可能比安裝花費更長的時間-請注意成功消息,並在“智能合約”>“實例化”列表中顯示[email protected],以確認它是否有效!
現在你的界面應該是這樣的:
提交和查詢事務
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和[email protected]。你將看到智能合約中定義的所有交易的列表。
現在你需要創建資產。右鍵單擊createMyAsset,然後選擇Submit Transaction。系統將要求你提供交易參數:嘗試[“ 001”,“my asset one”](或你喜歡的任何鍵和值,但請確保記住使用的鍵!)。
參數以JSON格式提交,因此請確保你完全按照顯示的方式輸入輸入內容,以便你根據此交易要求提交由2個字符串組成的數組。
接下來,以類似方式提交updateMyAsset。這次,為參數提供相同的鍵和不同的值,例如[“ 001”,“my asset two”]。因此,現在分類帳中的鍵001的值應該是“my asset two”。讓我們來檢查一下……
readMyAsset用於讀取而不是寫入分類帳,因此這次選擇查詢交易。輸入[“ 001”](或任何你設置的鍵)作為參數。你應該在輸出控制檯中看到以下內容:
<code>[SUCCESS] Returned value from readMyAsset: {"value":"my asset two"}
/<code>
恭喜你,你已經完成了第一個智能合約!
更多內容請訪問:flydean的博客 flydean.com
閱讀更多 flydean程序那些事 的文章