# Blockchain / 使用 BDK 來創建你的第一個區塊鏈吧! 嗨各位,不知道大家有沒有關注到這則新聞,比特幣最近創了歷史新高,原本走勢薄弱的以太幣也在短短一週內強勢拉盤了將近三十個點(撰文日期 2025.07.17),區塊鏈還真是個有趣的東西對吧!? 不過今天不和大家聊金融市場或加密貨幣,是想向大家介紹一個我最近發現的很有趣的工具: 「Blockchain Development Kits(BDK)」,它是由國泰金控區塊鏈團隊在 GitHub 上開源的區塊鏈部署工具,目的是協助同業與異業夥伴透過便捷的指令快速部署,進一步加快聯盟鏈推展速度! 以下我們將使用 Golang 以及 Docker-Compose,在 Ubuntu 中搭建起一個 Hyperledger Fabric,並撰寫一份智能合約使整個網路支援讀取與寫入資料。 ## Chapter 1: Network Architecture Overview ```mermaid graph TD subgraph "Orderer Organization" O1[orderer0:7050] O2[orderer1:7150] O1 <--> O2 end subgraph "Org0" P01[peer0:7051_Anchor] P02[peer1] end subgraph "Org1" P11[peer0] P12[peer1:7151_Anchor] end subgraph "Channel: test" CC[fabcar chaincode v1] end %% Orderers serve the channel O1 -.-> CC O2 -.-> CC %% Peers join channel and run chaincode P01 --> CC P02 --> CC P11 --> CC P12 --> CC %% Peer gossip within orgs P01 <--> P02 P11 <--> P12 classDef orderer fill:#e1f5fe,stroke:#0277bd,stroke-width:2px classDef peer fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px classDef chaincode fill:#e8f5e8,stroke:#388e3c,stroke-width:2px classDef external fill:#fff3e0,stroke:#f57900,stroke-width:2px class O1,O2 orderer class P01,P02,P11,P12 peer class CC chaincode class P01,P12 external ``` ## Chapter 2: Fabric Network :::danger 在開始前,請確認您的系統中已經安裝 Golang, node.js, docker 以及 docker-compose ! ::: ### 2.1 compose up orderer & peer #### 2.1.1 touch `create.json`@`~/.bdk` 我這邊的配置和官方文件不太一樣,因為在實作的過程中發現 `org0.peer0` 和 `org1.peer0` 兩個節點的端口會有衝突。另外,在之後我們是打算將 `org0.peer0` 和 `org1.peer1` 作為 Anchor Peer,所以做出了以下改動。 ```json= { "ordererOrgs": [ { "name": "Org0Orderer", "domain": "orderer.org0.example.com", "enableNodeOUs": true, "hostname": [ "orderer0", "orderer1" ], "ports": [ { "port": 7050, "isPublishPort": true, "operationPort": 8443, "isPublishOperationPort": true }, { "port": 7150, "isPublishPort": true, "operationPort": 8543, "isPublishOperationPort": true } ] } ], "peerOrgs": [ { "name": "Org0", "domain": "org0.example.com", "enableNodeOUs": true, "peerCount": 2, "userCount": 1, "ports": [ { "port": 7051, "isPublishPort": true, "operationPort": 9443, "isPublishOperationPort": true }, { "port": 7051, "isPublishPort": false, "operationPort": 9443, "isPublishOperationPort": false } ] }, { "name": "Org1", "domain": "org1.example.com", "enableNodeOUs": true, "peerCount": 2, "userCount": 1, "ports": [ { "port": 7051, "isPublishPort": false, "operationPort": 9443, "isPublishOperationPort": false }, { "port": 7151, "isPublishPort": true, "operationPort": 9543, "isPublishOperationPort": true } ] } ] } ``` #### 2.1.2 create network command `bdk` 指令語法設計的邏輯是: ```tex BDK,請在 [什麼平台] 上,對 [什麼東西] 執行 [什麼動作] ``` ```bash $ bdk fabric network create -f create.json --create-full # @~/.bdk/fabri ``` #### 2.1.3 build nodes with interactive mode ```bash= $ bdk fabric orderer up -i $ bdk fabric peer up -i ``` ### 2.2 build & join a channel ```bash= # Org0 的 peer0 建立新的 channel export BDK_ORG_NAME='Org0' export BDK_ORG_DOMAIN='org0.example.com' export BDK_HOSTNAME='peer0' bdk fabric channel create -i # Org0 的 peer0 加入 channel bdk fabric channel join -i # Org0 的 peer1 加入 channel export BDK_HOSTNAME='peer1' bdk fabric channel join -i # Org1 的 peer0 加入 channel export BDK_ORG_NAME='Org1' export BDK_ORG_DOMAIN='org1.example.com' export BDK_HOSTNAME='peer0' bdk fabric channel join -i # Org1 的 peer1 加入 channel export BDK_HOSTNAME='peer1' bdk fabric channel join -i ``` 互動模式的選項部分,則是統一選擇: ```bash= ✔ What is your channel name? › test ✔ Ordering service endpoint › orderer0.orderer.org0.example.com:7050 ``` ### 2.3 set up anchor peers ```bash= # 更新 Org0 的 anchor peer export BDK_ORG_NAME='Org0' export BDK_ORG_DOMAIN='org0.example.com' export BDK_HOSTNAME='peer0' bdk fabric channel update-anchorpeer -i # Org1 的 peer1 加入 channel export BDK_ORG_NAME='Org1' export BDK_ORG_DOMAIN='org1.example.com' export BDK_HOSTNAME='peer1' bdk fabric channel update-anchorpeer -i ``` ## Chapter 3: Smart Contract 詳細程式碼請參見 GitHub Repo: https://github.com/marvelcn015/bdk-fabcar ### 3.1 File Structure ``` chaincode/fabric/go/ ├── go.mod # Go module dependencies ├── main.go # Chaincode entry point ├── fabcar.go # Main chaincode structure and interface ├── business_logic.go # Core business operations (CRUD) ├── queries.go # Advanced query operations ├── utils.go # Validation and utility functions ├── fabcar_test.go # Comprehensive test suite └── README.md # This documentation ``` ### 3.2 API Methods #### 3.2.1 Initialize Chaincode ``` Function: Init Description: Initializes the chaincode with sample car data ``` #### 3.2.2 Query Single Car ``` Function: queryCar Arguments: [carKey] Example: queryCar "CAR0" ``` #### 3.2.3 Query All Cars ``` Function: queryAllCars Arguments: [] Example: queryAllCars ``` #### 3.2.4 Create New Car ``` Function: createCar Arguments: [carKey, make, model, color, owner, year, price] Example: createCar "CAR100" "BMW" "X5" "black" "John Doe" "2022" "75000" ``` #### 3.2.5 Update Car ``` Function: updateCar Arguments: [carKey, make, model, color, owner, year, price] Example: updateCar "CAR0" "Toyota" "Prius" "green" "Tomoko" "2018" "26000" ``` #### 3.2.6 Change Car Owner ``` Function: changeCarOwner Arguments: [carKey, newOwner] Example: changeCarOwner "CAR0" "Alice Smith" ``` #### 3.2.7 Delete Car ``` Function: deleteCar Arguments: [carKey] Example: deleteCar "CAR0" ``` #### 3.2.8 Query Cars by Owner ``` Function: queryCarsByOwner Arguments: [ownerName] Example: queryCarsByOwner "John Doe" ``` #### 3.2.9 Query Cars by Range ``` Function: queryCarsByRange Arguments: [startKey, endKey] Example: queryCarsByRange "CAR0" "CAR9" ``` #### 3.2.10 Get Car History ``` Function: getCarHistory Arguments: [carKey] Example: getCarHistory "CAR0" ``` #### 3.2.11 Get Car Count ``` Function: getCarCount Arguments: [] Example: getCarCount ``` ## Chapter 4: Chaincode Deployment ### 4.1 部署的五個階段 & 指令 ```mermaid flowchart TB A[Package<br/>打包] --> B[Install<br/>安裝] B --> C[Approve<br/>批准] C --> D[Commit<br/>部署] D --> E[Invoke<br/>執行] A --> A1[編譯程式碼] B --> B1[複製到各節點] C --> C1[組織決策階段] D --> D1[全網路部署] E --> E1[實際交易執行] style A fill:#e1f5fe style B fill:#e8f5e8 style C fill:#fff3e0 style D fill:#fce4ec style E fill:#f3e5f5 ``` ### 4.2 各階段參與者 | 階段 | 執行者 | 作用範圍 | 是否需要共識 | |------|--------|----------|-------------| | Package | 任一開發者 | 本地 | ❌ | | Install | 各 Peer 節點 | 節點層級 | ❌ | | Approve | 各組織 | 組織層級 | ❌ | | Commit | 任一組織 | 全網路 | ✅ | | Invoke | 任一授權用戶 | 全網路 | ✅ | ### 4.3 Install & Approve ```bash= # Org0 的 peer0 安裝、同意 Chaincode export BDK_ORG_NAME='Org0' export BDK_ORG_DOMAIN='org0.example.com' export BDK_HOSTNAME='peer0' bdk fabric chaincode install -i bdk fabric chaincode approve -i # Org1 的 Anchor Peer 也這麼做 export BDK_ORG_NAME='Org1' export BDK_ORG_DOMAIN='org1.example.com' export BDK_HOSTNAME='peer1' bdk fabric chaincode install -i bdk fabric chaincode approve -i # Org0 的 peer1 安裝 Chaincode export BDK_ORG_NAME='Org0' export BDK_ORG_DOMAIN='org0.example.com' export BDK_HOSTNAME='peer1' bdk fabric chaincode install -i # Org1 的 peer0 也這麼做 export BDK_ORG_NAME='Org1' export BDK_ORG_DOMAIN='org1.example.com' export BDK_HOSTNAME='peer0' bdk fabric chaincode install -i ``` ### 4.4 Commit & Init Invoke ```bash= export BDK_ORG_NAME='Org0' export BDK_ORG_DOMAIN='org0.example.com' export BDK_HOSTNAME='peer0' bdk fabric chaincode commit -i bdk fabric chaincode invoke -i ``` --- 接下來,就可以搭配各種自訂好的 Arguments 執行合約中的函數囉~ > BDK Offical Document: https://github.com/cathayddt/bdk/tree/master > > GitHub Repo: https://github.com/marvelcn015/bdk-fabcar > > 2025 / 07 / 17, by Aaron Yeh