This is my own reference implementation of Fabric SDK Design Spec
The major goals of this project are:
- Make it simple.
- Avoid conceptual and code level duplication.
- Build layers of abstraction to control complexity.
- Make easy to extend.
- Build mechanisms rather than type in manually.
- Make future proof.
- Provide fast and scalable API.
To understand its usage, see some test cases:
(expect io.grpc.StatusRuntimeException
(let [user (core/get-user "Org1MSP" "user1") ;; user == error!
mychannel (user/get-channel user "mychannel")]
(user/query-installed-chaincodes user (proto/get-random-node mychannel :peers))))
(expect true
(let [user (core/get-user "Org1MSP" "admin")
mychannel (user/get-channel user "mychannel")
chaincodes1 (user/query-installed-chaincodes user (proto/get-random-node mychannel :peers))]
(user/install-chaincode user (str "test" (System/currentTimeMillis)) "github.com/example_cc" "v1"
"/home/jc/Work/clojure-fabric/resources/gocc/src/github.com"
:golang (core/get-nodes mychannel :peers))
(= (inc (count chaincodes1))
(count (user/query-installed-chaincodes user (proto/get-random-node mychannel :peers))))))
(expect true
(let [orderer-admin (core/get-user "Orderer" "admin")
org1-admin (core/get-user "Org1MSP" "admin")
org2-admin (core/get-user "Org2MSP" "admin")
org1-user (core/get-user "Org1MSP" "user1")
org2-user (core/get-user "Org2MSP" "user1")
;; orderer is shared between Org1MSP and Org2MSP
orderer (first (core/get-nodes (core/get-user "Org1MSP" "user1") :orderers))
channel-name (str "mychannel" (System/currentTimeMillis))
config-update (assoc (user/tx-file->config-update "resources/fixture/balance-transfer/artifacts/channel/mychannel.tx")
:channel-id channel-name)
org1-peers [(core/find-peer "peer0" org1-user) (core/find-peer "peer1" org1-user)]
org2-peers [(core/find-peer "peer0" org2-user) (core/find-peer "peer1" org2-user)]]
(->> (user/clj-config-update->proto-byte-array config-update)
(user/create-or-update-channel-from-nodes org1-admin
channel-name
orderer
[org1-admin org2-admin orderer-admin]))
(user/new-channel! org1-admin {:name channel-name
:orderers {(:name orderer) orderer}
:peers org1-peers})
(user/new-channel! org2-admin {:name channel-name
:orderers {(:name orderer) orderer}
:peers org2-peers})
(let [org1-admin (core/get-user "Org1MSP" "admin")
org2-admin (core/get-user "Org2MSP" "admin")
genesis-block (channel/get-genesis-block (get-in org1-admin [:channels channel-name]))]
(every? (fn [resp]
(-> (.getResponse resp)
(.getStatus)
(= 200)))
(concat (channel/join-channel (user/get-channel org1-admin channel-name) org1-peers genesis-block)
(channel/join-channel (user/get-channel org2-admin channel-name) org2-peers genesis-block))))))
(expect (let [org1-admin (core/get-user "Org1MSP" "admin")]
(-> (channel/get-genesis-block (get-in org1-admin [:channels "mychannel"]))
(proto/proto->clj (proto/parse-trees :block-transaction))
(dissoc :metadata)))
(let [org1-admin (core/get-user "Org1MSP" "admin")
mychannel (user/get-channel org1-admin "mychannel")]
(-> (channel/query-block-by-number mychannel 0)
(first)
(dissoc :metadata))))
See more examples in core_test.clj
All major infrastructures were done - message building, message sending, event hub, parsing and building raw structures, and crypto suite.
- create-or-update-channel
- install-chaincode
- query-channels
- query-installed-chaincodes
Write test cases
- get-genesis-block
- join-channel
- query-blockchain-info
- query-block-by-number
- query-block-by-hash
- query-block-by-tx-id
- query-by-chaincode
- query-transaction
- query-instantiated-chaincodes
- send-instantiate-proposal
- send-transaction-proposal
- send-transaction (Use proto/send-proposal or chaincode/send-system-chaincode-request)
- send-upgrade-proposal
Write test cases
- decrypt
- derive-key
- encrypt
- generate-key
- hash
- import-key
- sign
- verify
- get-key Write test cases
- connect
- disconnect
- connected?
- register-block-event
- register-chaincode-event
- register-tx-event
- unregister-block-event
- unregister-chaincode-event
- unregister-tx-event
Write test cases
Not implemented yet
- send-broadcast
- send-deliver
Write test cases
- send-proposal - This is a low level function. See send-proposal in proto.clj
Write test cases
Copyright © 2017 Jong-won Choi.
Licensed under the Apache License, Version 2.0 (the "License")