Fisco Bcos學習 - 開發第一個區塊鏈應用

文章目錄

    • 一、前言
    • 二、業務場景分析:簡易資產管理系統
    • 三、智能合約設計與實現
      • 3.1 存儲結構設計
      • 3.2 接口設計
      • 3.3 完整合約代碼
    • 四、合約編譯與Java接口生成
    • 五、SDK配置與項目搭建
      • 5.1 獲取Java工程項目
      • 5.2 項目目錄結構
      • 5.3 引入Web3SDK
      • 5.4 證書與配置文件
    • 六、業務開發:Java客戶端實現
      • 6.1 核心類設計:AssetClient
        • 6.1.1 初始化
        • 6.1.2 合約對象創建
        • 6.1.3 接口調用
    • 七、項目運行與功能驗證
      • 7.1 編譯項目
      • 7.2 部署合約
      • 7.3 注冊資產
      • 7.4 查詢資產
      • 7.5 資產轉移
    • 八、參考資料

一、前言

在區塊鏈技術快速發展的今天,如何將其應用于實際業務場景成為開發者關注的重點。FISCO BCOS作為國產優秀的聯盟鏈平臺,為企業級區塊鏈應用開發提供了強大支持。本文將跟隨官方教程,詳細記錄基于FISCO BCOS構建第一個區塊鏈應用的全過程,涵蓋從業務分析到最終實現的完整流程。

二、業務場景分析:簡易資產管理系統

區塊鏈技術因其防篡改、可追溯的特性,在金融領域有著天然優勢。本次實踐選擇開發一個簡易的資產管理系統,主要實現以下核心功能:

  • 資產注冊:在區塊鏈上登記資產賬戶及初始金額
  • 資產轉賬:實現不同賬戶間的資產轉移
  • 資產查詢:查詢指定賬戶的資產余額

這個場景雖然簡單,但涵蓋了區塊鏈應用開發的核心流程,非常適合作為入門案例。

三、智能合約設計與實現

3.1 存儲結構設計

FISCO BCOS提供了合約CRUD接口開發模式,允許通過合約創建表結構并進行數據操作。針對資產管理需求,設計了名為t_asset的表:

  • account:資產賬戶,作為主鍵(string類型)
  • asset_value:資產金額(uint256類型)

該表結構示例如下:

accountasset_value
Alice10000
Bob20000

3.2 接口設計

根據業務目標,定義了三個核心接口:

  • select(string account):查詢資產金額
  • register(string account, uint256 amount):資產注冊
  • transfer(string from_asset_account, string to_asset_account, uint256 amount):資產轉移

3.3 完整合約代碼

pragma solidity ^0.4.24;
import "./Table.sol";contract Asset {// 事件定義,用于記錄關鍵操作event RegisterEvent(int256 ret, string account, uint256 asset_value);event TransferEvent(int256 ret, string from_account, string to_account, uint256 amount);constructor() public {// 構造函數中創建表createTable();}function createTable() private {TableFactory tf = TableFactory(0x1001);// 創建t_asset表,指定主鍵和字段tf.createTable("t_asset", "account", "asset_value");}function openTable() private returns (Table) {TableFactory tf = TableFactory(0x1001);Table table = tf.openTable("t_asset");return table;}// 查詢資產金額function select(string account) public constant returns (int256, uint256) {Table table = openTable();Entries entries = table.select(account, table.newCondition());uint256 asset_value = 0;if (0 == uint256(entries.size())) {return (-1, asset_value);} else {Entry entry = entries.get(0);return (0, uint256(entry.getInt("asset_value")));}}// 資產注冊function register(string account, uint256 asset_value) public returns (int256) {int256 ret_code = 0;int256 ret = 0;uint256 temp_asset_value = 0;(ret, temp_asset_value) = select(account);if (ret != 0) {Table table = openTable();Entry entry = table.newEntry();entry.set("account", account);entry.set("asset_value", int256(asset_value));int count = table.insert(account, entry);if (count == 1) {ret_code = 0;} else {ret_code = -2;}} else {ret_code = -1;}emit RegisterEvent(ret_code, account, asset_value);return ret_code;}// 資產轉移function transfer(string from_account, string to_account, uint256 amount) public returns (int256) {int ret_code = 0;int256 ret = 0;uint256 from_asset_value = 0;uint256 to_asset_value = 0;// 檢查轉出賬戶是否存在(ret, from_asset_value) = select(from_account);if (ret != 0) {ret_code = -1;emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 檢查轉入賬戶是否存在(ret, to_asset_value) = select(to_account);if (ret != 0) {ret_code = -2;emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 檢查余額是否充足if (from_asset_value < amount) {ret_code = -3;emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 檢查金額是否溢出if (to_asset_value + amount < to_asset_value) {ret_code = -4;emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}Table table = openTable();Entry entry0 = table.newEntry();entry0.set("account", from_account);entry0.set("asset_value", int256(from_asset_value - amount));int count = table.update(from_account, entry0, table.newCondition());if (count != 1) {ret_code = -5;emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}Entry entry1 = table.newEntry();entry1.set("account", to_account);entry1.set("asset_value", int256(to_asset_value + amount));table.update(to_account, entry1, table.newCondition());emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}
}

注意:該合約依賴FISCO BCOS提供的系統合約Table.sol,實現對表的CRUD操作

四、合約編譯與Java接口生成

Solidity合約無法被Java程序直接調用,需要通過控制臺工具將其編譯為Java類。具體步驟如下:

  1. Asset.solTable.sol放在console/contracts/solidity目錄
  2. 執行編譯腳本:
# 切換到console目錄
cd ~/fisco/console/
# 編譯合約,指定Java包名
./sol2java.sh org.fisco.bcos.asset.contract

編譯成功后會在console/contracts/sdk目錄生成:

  • abi目錄:存放合約ABI文件
  • bin目錄:存放合約字節碼文件
  • java目錄:存放生成的Java合約類

生成的Asset.java包含了與Solidity合約對應的Java接口:

package org.fisco.bcos.asset.contract;
public class Asset extends Contract {// 轉賬接口public RemoteCall<TransactionReceipt> transfer(String from_account, String to_account, BigInteger amount);// 注冊接口public RemoteCall<TransactionReceipt> register(String account, BigInteger asset_value);// 查詢接口public RemoteCall<Tuple2<BigInteger, BigInteger>> select(String account);// 加載合約public static Asset load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider);// 部署合約public static RemoteCall<Asset> deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider);
}

五、SDK配置與項目搭建

5.1 獲取Java工程項目

# 下載項目壓縮包
cd ~
curl -LO https://github.com/FISCO-BCOS/LargeFiles/raw/master/tools/asset-app.tar.gz
# 解壓項目
tar -zxf asset-app.tar.gz

5.2 項目目錄結構

asset-app/
├── build.gradle          # Gradle配置文件
├── gradle/
│   ├── wrapper/
│   │   ├── gradle-wrapper.jar
│   │   └── gradle-wrapper.properties
├── gradlew               # Linux執行腳本
├── gradlew.bat           # Windows執行腳本
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── org/
│   │   │       └── fisco/
│   │   │           └── bcos/
│   │   │               └── asset/
│   │   │                   ├── client/      # 客戶端調用類
│   │   │                   │   └── AssetClient.java
│   │   │                   └── contract/    # 合約Java類
│   │   │                       └── Asset.java
│   │   └── resources/
│   │       ├── applicationContext.xml       # 項目配置文件
│   │       ├── contract.properties          # 合約地址配置
│   │       ├── log4j.properties             # 日志配置
│   │       └── contract/
│   │           ├── Asset.sol                # Solidity合約
│   │           └── Table.sol
├── tool/
│   └── asset_run.sh     # 運行腳本

5.3 引入Web3SDK

項目已在build.gradle中配置好Web3SDK依賴:

repositories {maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }maven { url "https://dl.bintray.com/ethereum/maven/" }mavenCentral ()
}dependencies {compile('org.fisco-bcos:web3sdk:2.1.0')
}

5.4 證書與配置文件

拷貝區塊鏈節點的SDK證書到項目資源目錄:

cp fisco/nodes/127.0.0.1/sdk/* asset-app/src/test/resources/

六、業務開發:Java客戶端實現

6.1 核心類設計:AssetClient

AssetClient.java是業務邏輯的核心,負責合約的部署與調用,主要包含以下功能模塊:

6.1.1 初始化
// 初始化Web3j和Credentials對象
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Service service = context.getBean(Service.class);
service.run();ChannelEthereumService channelEthereumService = new ChannelEthereumService();
channelEthereumService.setChannelService(service);
Web3j web3j = Web3j.build(channelEthereumService, 1);Credentials credentials = Credentials.create(Keys.createEcKeyPair());
6.1.2 合約對象創建
// 部署合約
Asset asset = Asset.deploy(web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)).send();// 加載已部署合約
Asset asset = Asset.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit));
6.1.3 接口調用
// 查詢資產
Tuple2<BigInteger, BigInteger> result = asset.select(assetAccount).send();// 注冊資產
TransactionReceipt registerReceipt = asset.register(assetAccount, amount).send();// 資產轉賬
TransactionReceipt transferReceipt = asset.transfer(fromAccount, toAccount, amount).send();

七、項目運行與功能驗證

7.1 編譯項目

# 切換到項目目錄
cd ~/asset-app
# 編譯項目
./gradlew build

編譯成功后在dist目錄生成運行腳本。

7.2 部署合約

cd dist
bash asset_run.sh deploy
# 輸出示例:Deploy Asset successfully, contract address is 0xd09ad04220e40bb8666e885730c8c460091a4775

7.3 注冊資產

bash asset_run.sh register Alice 100000
# 輸出:Register account successfully => account: Alice, value: 100000bash asset_run.sh register Bob 100000
# 輸出:Register account successfully => account: Bob, value: 100000

7.4 查詢資產

bash asset_run.sh query Alice
# 輸出:account Alice, value 100000bash asset_run.sh query Bob
# 輸出:account Bob, value 100000

7.5 資產轉移

bash asset_run.sh transfer Alice Bob 50000
# 輸出:Transfer successfully => from_account: Alice, to_account: Bob, amount: 50000bash asset_run.sh query Alice
# 輸出:account Alice, value 50000bash asset_run.sh query Bob
# 輸出:account Bob, value 150000

八、參考資料

  • FISCO BCOS文檔:https://www.bookstack.cn/read/fisco-bcos-2.4-zh

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86298.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86298.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86298.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

軟件設計模式選擇、判斷解析-1

前言 解析是我個人的理解&#xff0c;相對來說我覺得是能對上定義的邏輯的 目錄 一.單選題 1.設計模式的兩大主題是(??)? 解析&#xff1a;無 2.下列模式中,屬于行為型模式的是&#xff08;&#xff09; 解析&#xff1a; 排除A和D&#xff0c;剩下的觀察者的“觀察”…

【編程基本功】Win11中Git安裝配置全攻略,包含Git以及圖形化工具TortoiseGit

1 摘要 今天田辛老師給大家帶來了一份超實用的博客&#xff0c;手把手教你安裝并配置 Git 及其圖形化界面 TortoiseGit&#xff0c;從官網下載到最終完成配置&#xff0c;每一個步驟都給大家講得明明白白&#xff0c;還配有相應的截圖&#xff0c;即使是新手小白也能輕松上手&…

細談QT信號與槽機制

轉自個人博客 信號與槽是我個人認為QT中最牛的機制之一&#xff0c;最近沒有其他的內容可寫&#xff0c;今天就來細細總結一下這個信號與槽機制。 1. 信號與槽機制概述 信號與槽機制可以理解為QT中的一種通信手段&#xff0c;在運行相關代碼前&#xff0c;分別聲明信號和槽&a…

Docker Swarm 與 Kubernetes 在集群管理上的主要區別

Docker Swarm 和 Kubernetes 是兩種流行的容器編排工具&#xff0c;它們都可以用于部署、管理和擴展容器化應用&#xff0c;但在集群管理方面有明顯的差異。 下面從多個維度對比它們在集群管理上的主要區別&#xff1a; ? 一、總體定位 項目Docker SwarmKubernetes官方支持D…

【StarRocks系列】查詢優化

步驟參考官網 分析查詢 | StarRocks StarRocks-Profile分析及優化指南 StarRocks-Profile分析及優化指南 - 經驗教程 - StarRocks中文社區論壇

軟測八股--測試理論 1 測試基礎

軟件測試&#xff1f; 發現程序中的側屋執行程序工程 目的&#xff1a;不僅是找出錯誤&#xff0c;還要分析錯誤產生原因和錯誤分布。檢查開發如阿健過程出現的bug&#xff0c;使開發人員及時修改。測試只能說明軟件中存在錯誤 目標&#xff1a;盡可能發現多的錯誤。一個好的…

mfc與vs成功在xp系統所需做的修改

目錄 前言一、MFC程序 inet_pton 、CT2A 未聲明問題1&#xff09;問題1&#xff1a;inet_pton &#xff1a;undeclared identifier - inet_pton未聲明2&#xff09;問題1&#xff1a;CT2A &#xff1a;undeclared identifier - CT2A未聲明 二、VS程序 使用事件、委托問題1&…

SpringMVC系列(三)(請求處理的十個實驗(上))

0 引言 作者正在學習SpringMVC相關內容&#xff0c;學到了一些知識&#xff0c;希望分享給需要短時間想要了解SpringMVC的讀者朋友們&#xff0c;想用通俗的語言講述其中的知識&#xff0c;希望與諸位共勉&#xff0c;共同進步&#xff01; 本系列會持續更新&#xff01;&…

Python案例練習:函數專題

用函數重新設計文章單詞出現次數程序 composition This is my family. We have a father, a mother and two brothers. My father is a doctor. He works in a hospital. My mother is a teacher. She teaches English in a school. My older brother is a student. He stu…

數據驅動 AI 時代:數據庫行業的技術躍遷與生態重構

在數據驅動的 AI 戰場&#xff0c;真正的決勝武器不是復雜精妙的算法模型&#xff0c;而是深埋在企業核心系統中的高維數據網絡&#xff08;圖&#xff09;。 時至今日&#xff0c;市場對AI的風向正從“狂飆突進”轉向“精耕細作”&#xff0c;就在上周&#xff08;米國時間6月…

碼分復用通俗理解

一、碼分復用&#xff08;CDMA&#xff09;的通俗理解 碼分復用&#xff08;Code Division Multiple Access&#xff0c;CDMA&#xff09;是一種讓多個用戶在同一時間、同一頻段上同時傳輸數據的技術。它的核心思想是&#xff1a;給每個用戶分配一個唯一的“編碼鑰匙”&#x…

MAC、IP地址、TCP、UDP、SSL、OSI模型

目錄 一 概要 二 MAC和IP地址 &#xff08;1&#xff09;什么是 MAC 地址&#xff1f; &#xff08;2&#xff09;什么是 IP 地址&#xff1f; &#xff08;3&#xff09;MAC 地址 vs IP 地址對比表 &#xff08;4&#xff09;總結一下 二 TCP、UDP、SSL詳細介紹 &#…

弱口令介紹及破解方式筆記

一、弱口令的定義與危害 弱口令是指容易被猜測或破解的密碼&#xff0c;通常包含簡單數字組合&#xff08;如“123456”&#xff09;、鍵盤連續字符&#xff08;如“qwerty”&#xff09;、個人信息&#xff08;如生日、姓名&#xff09;或常見詞匯&#xff08;如“password”…

Kotlin 中ArrayList、listOf、arrayListOf 和 mutableListOf區別

在 Kotlin 中&#xff0c;ArrayList、listOf、arrayListOf 和 mutableListOf 是常用的集合創建方式&#xff0c;但它們在類型、可變性和使用場景上有明顯區別。以下是核心對比&#xff1a; 一、基本定義與類型 創建方式類型可變性底層實現ArrayList<T>()ArrayList<T…

C盤清理技巧分享:釋放寶貴空間,提升電腦性能

Hi&#xff0c;我是布蘭妮甜 &#xff01;隨著電腦使用時間的增長&#xff0c;C盤空間逐漸被各種文件占據&#xff0c;導致系統運行緩慢、程序響應遲鈍。對于許多用戶來說&#xff0c;C盤空間不足是一個常見且令人頭疼的問題。本文將分享一系列實用的C盤清理技巧&#xff0c;幫…

【 感知集群】大規模分布式基礎設施的AI賦能藍圖

第一部分&#xff1a;AIOps基礎——從被動響應到預測性運維 在本報告的初始部分&#xff0c;我們將為管理一個復雜的大規模集群建立關鍵的基線。我們認為&#xff0c;在追求高級優化或未來主義架構之前&#xff0c;一個強大、由人工智能驅動的運維基礎是不可或缺的。本部分將詳…

《R循環:深度解析與高效使用技巧》

《R循環:深度解析與高效使用技巧》 引言 R語言作為一種功能強大的統計計算和圖形顯示語言,被廣泛應用于科研、數據分析、金融等領域。R循環是R語言中的核心概念之一,對于提高編程效率、處理復雜數據至關重要。本文將深度解析R循環,并介紹高效使用技巧,幫助讀者更好地掌握…

Windows WSL安裝Emscripten?/emsdk(失敗)

前面說過&#xff0c;在CMD、PS下&#xff0c;根本安裝不了。那只能試試在WSL安裝了。 安裝ubuntu 管理員運行PowerShell wsl --install ubuntu自帶python3&#xff0c;不需要安裝。 安裝 我就奇怪了&#xff0c;都說得頭頭是道&#xff0c;實際上一操作就出問題&#xff…

SpringBoot + EMQX 通過MQTT協議和下位機建立通訊并獲取下位機的監測數據-->測試

一、說明 在上一個博客中&#xff0c;我們部署了 EMQX 服務器&#xff0c;實現了 SpringBoot EMQX 通過MQTT協議和下位機建立通訊并獲取下位機的監測數據的編碼。現在我們對編碼進行進一步的測試。 二、編碼測試 2.1 在 EMQX 服務器開啟客戶端認證 這里的客戶端認證&#xf…

#17 修改開源模型以適配新任務

在Kaggle的評論區看到有選手想用Swin Transformer來做回歸任務,從這個片段可以窺見修改模型的一些思路,于是記錄下來學習一下 基于 torchvision Swin_B 模型的特征提取 from torchvision.models.swin_transformer import swin_b, Swin_B_Weights, swin_v2_b, Swin_V2_B_Weig…