基于fabric 0.6定制智能合约
来源:互联网 发布:中美进出口数据 编辑:程序博客网 时间:2024/05/29 19:27
- fabric部署与管理
- 1 git地址
- 2 部署
- 3 使用chaincode
- fabric源码智能合约源码解析
- 1 go语言又称golang
- 2 智能合约例子
- 3 核心接口
- 定制智能合约
- 1 智能合约
- 2 编译调试
目前fabric 0.6为稳定版本,fabric 1.0为最新版,并持续更新中
IBM中国研究院开发的超能云(SuperVessel)平台提供了给区块链爱好者、开发者的区块链开发测试环境。通过该平台,用户能够免费、超快速创建基于Hyperledger Fabric的多节点区块链、并在自己的链上花式玩转智能合约。
https://my.oschina.net/u/1431433/blog/712869
1 fabric部署与管理
1.1 git地址
https://github.com/hyperledger/fabric
默认是最新版1.0,可以自己切换到v0.6分支
1.2 部署
环境:Ubuntu 16.04 64位
安装Docker,Docker-compose,fabric部署,以pbft模式启动fabric
参考文档:http://www.cnblogs.com/sclczk/p/6552845.html
重启服务
systemctl restart docker.service
启动 4 个 PBFT peer 节点 + 1 个 CA 节点 + 1 个 Blockchain-explorer,并启用 CA 功能。
docker-compose -f 4-peers-with-membersrvc-explorer.yml up
1.3 使用chaincode
https://yeasy.gitbooks.io/blockchain_guide/content/fabric/v0.6/usage.html
或参考https://bitshuo.com/topic/58870c418d8be16a4ff73081
进入一个节点
docker exec -it pbft_vp0_1 bash
2 fabric源码智能合约源码解析
2.1 go语言(又称golang)
go IDE:Gogland
http://www.mamicode.com/info-detail-1701831.html
2.2 智能合约例子
相关例子在如下文件夹中
这里列举了如何做一个map和table
2.3 核心接口
在fabric/core/chaincode/shim中的interfaces.go
type ChaincodeStubInterface interface { // Get the arguments to the stub call as a 2D byte array GetArgs() [][]byte // Get the arguments to the stub call as a string array GetStringArgs() []string // Get the transaction ID GetTxID() string // InvokeChaincode locally calls the specified chaincode `Invoke` using the // same transaction context; that is, chaincode calling chaincode doesn't // create a new transaction message. InvokeChaincode(chaincodeName string, args [][]byte) ([]byte, error) // QueryChaincode locally calls the specified chaincode `Query` using the // same transaction context; that is, chaincode calling chaincode doesn't // create a new transaction message. QueryChaincode(chaincodeName string, args [][]byte) ([]byte, error) // GetState returns the byte array value specified by the `key`. GetState(key string) ([]byte, error) // PutState writes the specified `value` and `key` into the ledger. PutState(key string, value []byte) error // DelState removes the specified `key` and its value from the ledger. DelState(key string) error // RangeQueryState function can be invoked by a chaincode to query of a range // of keys in the state. Assuming the startKey and endKey are in lexical // an iterator will be returned that can be used to iterate over all keys // between the startKey and endKey, inclusive. The order in which keys are // returned by the iterator is random. RangeQueryState(startKey, endKey string) (StateRangeQueryIteratorInterface, error) // CreateTable creates a new table given the table name and column definitions CreateTable(name string, columnDefinitions []*ColumnDefinition) error // GetTable returns the table for the specified table name or ErrTableNotFound // if the table does not exist. GetTable(tableName string) (*Table, error) // DeleteTable deletes an entire table and all associated rows. DeleteTable(tableName string) error // InsertRow inserts a new row into the specified table. // Returns - // true and no error if the row is successfully inserted. // false and no error if a row already exists for the given key. // false and a TableNotFoundError if the specified table name does not exist. // false and an error if there is an unexpected error condition. InsertRow(tableName string, row Row) (bool, error) // ReplaceRow updates the row in the specified table. // Returns - // true and no error if the row is successfully updated. // false and no error if a row does not exist the given key. // flase and a TableNotFoundError if the specified table name does not exist. // false and an error if there is an unexpected error condition. ReplaceRow(tableName string, row Row) (bool, error) // GetRow fetches a row from the specified table for the given key. GetRow(tableName string, key []Column) (Row, error) // GetRows returns multiple rows based on a partial key. For example, given table // | A | B | C | D | // where A, C and D are keys, GetRows can be called with [A, C] to return // all rows that have A, C and any value for D as their key. GetRows could // also be called with A only to return all rows that have A and any value // for C and D as their key. GetRows(tableName string, key []Column) (<-chan Row, error) // DeleteRow deletes the row for the given key from the specified table. DeleteRow(tableName string, key []Column) error // ReadCertAttribute is used to read an specific attribute from the transaction certificate, // *attributeName* is passed as input parameter to this function. // Example: // attrValue,error:=stub.ReadCertAttribute("position") ReadCertAttribute(attributeName string) ([]byte, error) // VerifyAttribute is used to verify if the transaction certificate has an attribute // with name *attributeName* and value *attributeValue* which are the input parameters // received by this function. // Example: // containsAttr, error := stub.VerifyAttribute("position", "Software Engineer") VerifyAttribute(attributeName string, attributeValue []byte) (bool, error) // VerifyAttributes does the same as VerifyAttribute but it checks for a list of // attributes and their respective values instead of a single attribute/value pair // Example: // containsAttrs, error:= stub.VerifyAttributes(&attr.Attribute{"position", "Software Engineer"}, &attr.Attribute{"company", "ACompany"}) VerifyAttributes(attrs ...*attr.Attribute) (bool, error) // VerifySignature verifies the transaction signature and returns `true` if // correct and `false` otherwise VerifySignature(certificate, signature, message []byte) (bool, error) // GetCallerCertificate returns caller certificate GetCallerCertificate() ([]byte, error) // GetCallerMetadata returns caller metadata GetCallerMetadata() ([]byte, error) // GetBinding returns the transaction binding GetBinding() ([]byte, error) // GetPayload returns transaction payload, which is a `ChaincodeSpec` defined // in fabric/protos/chaincode.proto GetPayload() ([]byte, error) // GetTxTimestamp returns transaction created timestamp, which is currently // taken from the peer receiving the transaction. Note that this timestamp // may not be the same with the other peers' time. GetTxTimestamp() (*timestamp.Timestamp, error) // SetEvent saves the event to be sent when a transaction is made part of a block SetEvent(name string, payload []byte) error}
3 定制智能合约
3.1 智能合约
写的一个例子:
package mainimport ( "errors" "fmt" "encoding/json" "github.com/hyperledger/fabric/core/chaincode/shim")// SimpleChaincode example simple Chaincode implementationtype SimpleChaincode struct {}func main() { err := shim.Start(new(SimpleChaincode)) if err != nil { fmt.Printf("Error starting Simple chaincode: %s", err) }}type Location struct { Id string Status string locx string locy string}// Init resets all the thingsfunc (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting 1") } return nil, nil}// Invoke isur entry point to invoke a chaincode functionfunc (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { fmt.Println("invoke is running " + function) // Handle different functions if function == "init" { return t.Init(stub, "init", args) } else if function == "write" { return t.write(stub, args) } fmt.Println("invoke did not find func: " + function) return nil, errors.New("Received unknown function invocation")}// Query is our entry point for queriesfunc (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { fmt.Println("query is running " + function) // Handle different functions if function == "read" { //read a variable return t.read(stub, args) } fmt.Println("query did not find func: " + function) return nil, errors.New("Received unknown function query")}// write - invoke function to write key/value pairfunc (t *SimpleChaincode) write(stub shim.ChaincodeStubInterface, args []string) ([]byte,error) { if len(args) != 4{ return nil, errors.New("Incorrect number of arguments. Expecting 4") } var err error location := Location {Id:args[0],Status:args[1]+","+args[2]+","+args[3],locx:args[2],locy:args[3]} locationlBytes,err:= json.Marshal(&location) str := string(locationlBytes[:]) fmt.Println(str) if err != nil{ fmt.Print(err) } err = stub.PutState(location.Id,locationlBytes) if err !=nil{ return nil,errors.New("PutState Error" + err.Error()) } return nil,nil}// read - query function to read key/value pairfunc (t *SimpleChaincode) read(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var key, jsonResp string var err error if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting name of the key to query") } key = args[0] valAsbytes, err := stub.GetState(key) if err != nil { jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}" return nil, errors.New(jsonResp) } return valAsbytes, nil}
3.2 编译调试
go build
http://blog.csdn.net/h363659487/article/details/72768211
部署自己写的智能合约时,先上传到github,然后进入一个vp节点: docker exec -it pbft_vp0_1 bash
,
通过github下载到节点里面。
注意路径中的github.com其实就是一个文件名
- 基于fabric 0.6定制智能合约
- Fabric 智能合约具体代码模板分析
- Fabric智能合约编译与测试环境搭建
- 智能合约
- 在 hyperledger fabric 环境对Validating Peers布署 chaincode (智能合约)
- 开源|基于区块链的智能合约快速上手
- 【转载】智能合约简介
- 智能合约编写实例
- 智能合约的安全问题
- truffle部署智能合约
- 智能投票合约
- 【智能合约】Solidity
- 智能合约不智能
- 何编写智能合约
- 编写智能合约
- 『0004』- 基于Ethereum Wallet的Solidity HelloWorld智能合约(Smart Contract)
- 以太网智能合约开发参考
- 区块链2.0:智能合约
- WAVE文件格式说明
- 学习互联网架构第十课(并发类容器)
- Linux环境的函数
- VSCrawler 爬虫 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 解决方案
- LeetCode-94. Binary Tree Inorder Traversal
- 基于fabric 0.6定制智能合约
- 面试题目44—扑克牌的顺子
- 解决RecyclerView代码复用问题
- 无领导小组讨论注意事项
- 面试题45—圆圈中最后剩下的数字
- 浅谈Web网站架构演变过程
- 基于C++的PID控制器
- 一犯再犯的面试错误
- Java发送邮件