华为云用户手册

  • 请求示例 { "orgID" : "4f1439758ebb41f7411b5f684b67713c08b89198", "channelID" : "mychannel", "cryptoMethod" : "SW", "cert" : "-----BEGIN CERTIFICATE-----\n...\n...\n-----END CERTIFICATE-----", "sk" : "------BEGIN PRIVATE KEY-----\n...\n...\n-----END PRIVATE KEY-----", "timestamp" : "2020-10-27T17:28:16+08:00", "orderIndex" : 1, "vcIndex" : 0}
  • 请求参数 表1 请求Body参数 参数 是否必选 参数类型 描述 orgID 是 String 组织id channelID 是 String 通道id cryptoMethod 是 String 加密方法,目前固定为SW cert 是 String 证书 sk 是 String 私钥 timestamp 是 String 时间戳 consumer 是 String 订单申请者身份标识 orderSeq 是 String 订单序列号
  • 请求参数 表1 请求Body参数 参数 是否必选 参数类型 描述 orgID 是 String 组织id channelID 是 String 通道id cryptoMethod 是 String 加密方法,目前固定为SW cert 是 String 用户证书,每行末尾均需要增加显式换行符\n sk 是 String 用户私钥,每行末尾均需要增加显式换行符\n timestamp 是 String 时间戳 orderIndex 是 String 订单索引 vcIndex 是 String 凭证索引
  • 查询文件历史版本 接口方法 func (bc *BsClient) GetFileHistory(fileName string) ([]*bstore.FileHistory, error) 参数说明 参数 类型 说明 fileName string 查询的链上文件名。 返回值 类型 说明 []*FileHistory 文件历史版本信息列表,每条历史版本信息包含版本号、文件哈希值、首次上链时间、更新时间、上传者数据。 error 查询成功返回类型为nil,反之返回error。 父主题: 其他查询
  • 链代码示例(2.0风格) Fabric架构版本的 区块链 实例: 如下是一个账户转账的链代码示例(2.0风格)仅供安装实例化,若您需要调测请参考Fabric官方示例中的链代码。 package main import ( "errors" "fmt" "strconv" "github.com/hyperledger/fabric-contract-api-go/contractapi") // 链码实现type ABstore struct { contractapi.Contract} // 初始化链码数据,实例化或者升级链码时自动调用func (t *ABstore) Init(ctx contractapi.TransactionContextInterface, A string, Aval int, B string, Bval int) error { // 使用println函数输出的信息会记录在链码容器日志中 fmt.Println("ABstore Init") var err error fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // 将状态数据写入账本 err = ctx.GetStub().PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return err } err = ctx.GetStub().PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return err } return nil} // A转账X给Bfunc (t *ABstore) Invoke(ctx contractapi.TransactionContextInterface, A, B string, X int) error { var err error var Aval int var Bval int // 从账本获取状态数据 Avalbytes, err := ctx.GetStub().GetState(A) if err != nil { return fmt.Errorf("Failed to get state") } if Avalbytes == nil { return fmt.Errorf("Entity not found") } Aval, _ = strconv.Atoi(string(Avalbytes)) Bvalbytes, err := ctx.GetStub().GetState(B) if err != nil { return fmt.Errorf("Failed to get state") } if Bvalbytes == nil { return fmt.Errorf("Entity not found") } Bval, _ = strconv.Atoi(string(Bvalbytes)) // 执行转账 Aval = Aval - X Bval = Bval + X fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) // 将状态数据重新写回账本 err = ctx.GetStub().PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return err } err = ctx.GetStub().PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return err } return nil} // 账户注销func (t *ABstore) Delete(ctx contractapi.TransactionContextInterface, A string) error { // 从账本中删除账户状态 err := ctx.GetStub().DelState(A) if err != nil { return fmt.Errorf("Failed to delete state") } return nil} // 账户查询func (t *ABstore) Query(ctx contractapi.TransactionContextInterface, A string) (string, error) { var err error // 从账本获取状态数据 Avalbytes, err := ctx.GetStub().GetState(A) if err != nil { jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" return "", errors.New(jsonResp) } if Avalbytes == nil { jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" return "", errors.New(jsonResp) } jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" fmt.Printf("Query Response:%s\n", jsonResp) return string(Avalbytes), nil} func main() { cc, err := contractapi.NewChaincode(new(ABstore)) if err != nil { panic(err.Error()) } if err := cc.Start(); err != nil { fmt.Printf("Error starting ABstore chaincode: %s", err) }} 父主题: Go语言链代码开发
  • 查询文件操作记录 接口方法 func (bc *BsClient) GetFileOperation(fileName, startTime, endTime string) ([]*bstore.StorageEvent, error) 参数说明 参数 类型 说明 fileName string 查询的链上文件名。 startTime string 查询记录的起始时间(秒时间戳)。 endTime string 查询记录的结束时间(秒时间戳) 返回值 类型 说明 []*StorageEvent 文件操作记录列表,每条操作记录包含操作者、操作类型、时间数据。 error 查询成功返回类型为nil,反之返回error。 父主题: 其他查询
  • SDK接口 表1 ContractStub合约信息&状态数据库访问接口 接口 说明 String funcName() 功能:获取智能合约请求中指定的智能合约函数名称 入参:无 返回值:智能合约函数名称 byte[][] parameters() 功能: 获取请求参数 入参:无 返回值:用户执行智能合约逻辑时传入的多个参数,每个参数以[]byte表示 String chainId() 功能:获取智能合约所在链ID 入参:无 返回值:链ID String contractName() 功能:获取智能合约名称 入参:无 返回值:智能合约名称 byte[] getKv(String key) throws ContractException 功能:获取状态数据库中某个key对应的value; 入参:某个键值对的key信息,只支持string类型,不可为空 返回值:value值,目前只支持[]byte类型;当key不存在时,value为null 抛出异常:当网络出错,消息超时等,抛出异常 void putKv(String key, byte[] value) throws ContractException 功能:写状态数据库操作,此接口只是将key、value形成写集,打包到交易中,只有当交易排序、出块、并校验通过之后,才会将key/value写入到状态数据库中 入参:要写入的键值对,要求key != "",并且value != null 抛出异常:当网络出错,消息超时等,抛出异常 void delKv(String key) throws ContractException 功能:删除状态数据库中的key及其对应的value,此接口只是将待删除的key放入写集,打包到交易中,只有当交易排序、出块、并校验通过之后,才会将key删除 入参:要删除的key,要求key != "" 抛出异常:当网络出错,消息超时等,抛出异常 Iterator getIterator(String startKey, String endKey) throws ContractException 功能:查询状态数据库中,按字典序,以startKey开头,以endKey结尾的所有状态数据,结果以迭代器的形式呈现;注意,查询范围是左闭右开的,[startKey, endKey) 例如:startKey="11",endKey="14",所有key都是整数的话,则查询的结果中,key值包括:"11","12","13",不包括"14" 入参:startKey是待查询状态数据的按字典序的起始key,startKey != "",endKey是待查询的状态数据的按字典序的结束key,endKey!= ""; 返回值:Iterator是查询结果的迭代器,可以通过此迭代器,按顺序读取查询结果 抛出异常:当网络出错,消息超时等,抛出异常 HistoryIterator getKeyHistoryIterator(String key) throws ContractException 功能:查询一个key对应的所有历史的value 例如:一个key的value曾经为1,2,3,当前value为4,则返回的迭代器结果中按顺序包含了1,2,3,4 入参:key是待查询历史value值的key信息,key != "" 返回值:HistoryIterator是按顺序包含了历史value结果的迭代器结构体变量 抛出异常:当网络出错,消息超时等,抛出异常 void saveComIndex(String indexName, String[] attributes, String objectKey) throws ContractException 功能:为objectKey保存索引信息,indexName_attributes_objectKey构成索引信息,注意,此处只是形成索引信息的写集,只有当含有此写集的交易经过排序、出块,并校验通过后,才会写入状态数据库 例如:存储key/value信息,key="zhangsan",value={height=175, sex="male"},如果以sex="male"作为查询条件,查询所有的key/value, 则需要反序列化所有的value,性能损耗较大,因此,为当前key/value建立一个sex相关的索引:indexName="sex",attributes=[]string{"male"},objectKey="zhangsan, 入参:indexName 索引标记,indexName != "",attributes需要当做索引的属性,至少包含一个属性信息,objectKey 待索引的key值,objectKey != "" 抛出异常:当网络出错,消息超时等,抛出异常 Iterator getKvByComIndex(String indexName, String[] attributes) throws ContractException 功能:通过索引信息,查找满足某种查询条件的key/value,key/value以迭代器的形式输出 入参:indexName 索引标记,indexName != "",attributes需要当做索引的属性,至少包含一个属性信息 返回值:满足索引条件的key/value的迭代器变量 抛出异常:当网络出错,消息超时等,抛出异常 void delComIndexOneRow(String indexName, String[] attributes, String objectKey) throws ContractException 功能:删除objectKey的某个索引,indexName_attributes_objectKey构成索引信息,注意,此处只是形成索引信息的写集,只有当含有此写集的交易经过排序、出块,并校验通过后,才会写入状态数据库 入参:indexName 索引标记,indexName != "",attributes需要当做索引的属性,至少包含一个属性信息,objectKey 待索引的key值,objectKey != "" 抛出异常:当网络出错,消息超时等,抛出异常 表2 Iterator迭代器接口 接口 说明 boolean next() throws ContractException 功能:检查迭代器中是否还有下一个key/value 入参:无 返回值:bool值,true代表还有下一个值 抛出异常:当网络出错,消息超时等,抛出异常 String key() throws ContractException 功能:从迭代器中获取key 入参:无 返回值:key值 抛出异常:当网络出错,消息超时等,抛出异常 byte[] value() throws ContractException 功能:从迭代器中获取value 入参:无 返回值:value值类型为字节数组 抛出异常:当网络出错,消息超时等,抛出异常 void close() 功能:使用完迭代器之后,需要关闭迭代器 入参:无 抛出异常:当网络出错,消息超时等,抛出异常 表3 HistoryIterator查询某个key历史value信息的迭代器接口 接口 说明 long blockNum(); 功能:获取当前迭代位置(某笔交易)的 BlockNum 入参:无 int txNum(); 功能:获取当前迭代位置(某笔交易)的 TxNum 入参:无 byte[] txHash(); 功能:获取当前迭代位置((某笔交易))的hash 入参:无 boolean isDeleted(); 功能:被查询的key,当前是否已经在状态数据库中被删除 入参:无 long timestamp(); 功能:返回当前迭代位置(某笔交易)的时间戳 入参:无 父主题: JAVA合约开发
  • 查询交易执行结果 消息构建。 接口方法 func (msg *QueryRawMessage) BuildTxRawMessage(chainID string, txHash []byte) (*common.RawMessage, error) 参数说明 参数 类型 说明 chainID string 链ID。 txHash []byte 交易Hash。 返回值 类型 说明 *common.RawMessage 查询交易执行结果需发送的消息。 error 构建成功返回类型为nil,反之返回error。 消息发送。 接口方法 QueryAction.class func (action *QueryAction) GetTxResultByTxHash(rawMsg *common.RawMessage) (*common.RawMessage, error) 参数说明 参数 类型 说明 rawMsg *common.RawMessage 上述生成的查询指定交易执行结果的消息。 返回值 类型 说明 *common.RawMessage 用于获取包含发送结果的消息。 error 发送成功返回类型为nil,反之返回error。 父主题: 其他查询
  • SDK接口 合约SDK提供如下API接口,可以在合约文件中进行调用。这些API按照功能可以划分为: 表1 stub接口 接口 说明 FuncName() string 获取智能合约请求中指定的智能合约函数名称。 Parameters() [][]byte 获取请求参数。 ChainID() string 获取智能合约所在链ID。 ContractName() string 获取智能合约名称。 TxTimestamp() time.Time 获取本次交易的时间戳。 表2 ContractStub接口 接口 说明 GetKV(key string) ([]byte, error) 功能:获取状态数据库中某个key对应的value。 入参:某个键值对的key信息,不可为空。 返回值:返回[]byte类型的value值;当key不存在时,value为nil。 error:当网络出错,状态数据库出错,返回error信息。 PutKV(key string, value []byte) error 功能:写状态数据库操作,将key、value形成写集,打包到交易中,当交易排序、出块、并校验通过之后,将key/value写入到状态数据库中。入参:要写入的键值对要求key != "",并且value != nil。 error:入参错误。 PutKVCommon(key string, value interface{}) error 功能:写状态数据库操作,与PutKV功能相同;与PutKV接口的不同之处在于 value不是[]byte类型,而是一个实现了Marshal(v interface{}) ([]byte, error)接口的数据,接口内部,会将value通过Marshal接口序列化,然后再形成写集。 入参:要写入的键值对,要求key != "",并且value实现了Marshal接口,可以序列化为[]byte。 error:入参错误。 DelKV(key string) error 功能:删除状态数据库中的key及其对应的value,此接口只是将待删除的key放入写集,打包到交易中,当交易排序、出块、并校验通过之后,将key删除。 入参:要删除的key要求key != ""。 error:入参错误。 GetIterator(startKey, endKey string) (Iterator, error) 功能:查询状态数据库中,按字典序,以startKey开头,以endKey结尾的所有状态数据,结果以迭代器的形式呈现;查询范围是左闭右开的,[startKey, endKey)。 入参:startKey是待查询状态数据的按字典序的起始key,startKey != "",endKey是待查询的状态数据的按字典序的结束key,endKey!= ""。 返回值:Iterator是查询结果的迭代器,可以通过此迭代器,按顺序读取查询结果。 error:入参或网络错误。 GetKeyHistoryIterator(key string) (HistoryIterator, error) 功能:查询一个key对应的所有历史的value 入参:key是待查询历史value值的key信息,key != ""。 返回值:HistoryIterator是按顺序返回包含历史value结果的迭代器结构体变量。 error:入参或网络错误。 SaveComIndex(indexName string, attributes []string, objectKey string) error 功能:为objectKey保存索引信息,indexName_attributes_objectKey构成索引信息,注意,此处只是形成索引信息的写集,只有当含有此写集的交易经过排序、出块,并校验通过后,才会写入状态数据库。 入参:indexName 索引标记,indexName != "",attributes需要当做索引的属性,至少包含一个属性信息,objectKey 待索引的key值,objectKey != ""。 error:入参错误。 GetKVByComIndex(indexName string, attributes []string) (Iterator, error) 功能:通过索引信息,查找满足某种查询条件的key/value,key/value以迭代器的形式输出。 入参:indexName 索引标记,indexName != "",attributes需要当做索引的属性,至少包含一个属性信息 返回值:满足索引条件的key/value的迭代器变量。 error:入参或网络错误。 DelComIndexOneRow(indexName string, attributes []string, objectKey string) error 功能:删除objectKey的某个索引,indexName_attributes_objectKey构成索引信息,注意,此处只是形成索引信息的写集,只有当含有此写集的交易经过排序、出块,并校验通过后,才会写入状态数据库。 入参:indexName 索引标记,indexName != "",attributes需要当做索引的属性,至少包含一个属性信息,objectKey 待索引的key值,objectKey != ""。 error:入参错误。 SplitComKey(comKey string) (string, []string, error) 功能:将查询到的复合键分离为objectkey和对应的attributes。 返回值:objectkey,和attributes字符串数组。 GetKVByPartialComKey(objectType string, attributes []string) (Iterator, error) 功能:部分复合键查询。 返回值:Iterator包含查询返回信息,支持迭代获取。 表3 HistoryIterator迭代器接口 接口 说明 Version() (uint64, int32) 获取当前迭代位置(某笔交易)的 BlockNum 和 TxNum。 TxHash() []byte 获取当前迭代位置(某笔交易)的hash。 IsDeleted() bool 被查询的key,当前是否已经在状态数据库中被删除。 Timestamp() uint64 返回当前迭代位置(某笔交易)的时间戳。 父主题: Go合约开发
  • 调用合约 Main.go是一个简单的客户端应用示例程序,主要是为了方便用户熟悉客户端开发的流程,主要包含以下步骤: //1.导入相关包:Sdk包中提供了一些API,以便用户的应用程序能够访问链代码。import ( "fmt" "github.com/hyperledger/fabric-sdk-go/pkg/client/channel" "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" ……)//2.创建文件配置:这部分封装了应用开发必要的一些公共配置,包括sdk配置文件路径、组织名var ( configFile = "/root/fabric-go-demo/config/go-sdk-demo-channel-sdk-config.yaml" org = "9103f17cb6b4f69d75982eb48bececcc51aa3125" ……)//3.加载配置文件loadConfig()//4. 初始化sdkinitializeSdk()//5. 执行链代码,将数据写入账本,key = "testuser",value= "100"insert("insert",[][]byte{ []byte("testuser"), []byte("100"),})//6.查询链代码,输出查询结果,key = "testuser" query("query",[][]byte{[]byte("testuser"),}) 表1 调用函数介绍 函数名 说明 getOptsToInitializeSDK 解析配置文件,创建并返回fabsdk.Option对象。 GetDefaultChaincodeId 解析配置文件,返回chaincodeID。 GetDefaultChannel 解析配置文件,返回channelID。 UserIdentityWithOrgAndName 用户身份验证,输入为组织名和用户名,返回为验证结果。 ChannelClient 创建*channel.Client对象,输入为组织名、用户名以及通道ID,返回*channel.Client对象。 insert 将数据写入账本,输入参数为链码的对应方法名称以及要插入的键值对,返回为写入的结果。 query 查询链上信息,输入参数为链码的对应方法名称以及要查询的数据,返回为查询的结果。
  • 通过内存传入私钥 如果用户需要对私钥文件进行加密,并在demo中解密后传入FabricSDK。 对于TLS私钥 在main.go文件的initializeSdk函数中,按如下方式调用函数: encryptedtlsKey,err := GetTlsCryptoKey(org) //从配置文件指定路径下读取加密过的TLS私钥//用户按照自行规定的加解密方法对encryptedtlsKey进行解密得到decryptedTlsKey字符串SetClientTlsKey(decryptedTlsKey) //将解密后的TLS私钥传入Fabric-SDK,实现通过内存传入TLSKey 对于MSP私钥 在main.go文件的insert函数中,按如下方式调用函数: encryptedbytekey,_:= GetPrivateKeyBytes(org) //从配置文件指定路径下读取加密过的MSP私钥//用户按照自行规定的加解密方法对encryptedbytekey进行解密得到decryptedKey字符串SetPrivateKey(decryptedKey) //将解密后的MSP私钥赋值给全局变量privateKey并通过该变量传入
  • 下载SDK和证书 登录区块链服务管理控制台。 在“实例管理”页面,选择“Hyperledger Fabric增强版”页签,单击对应实例卡片上的“获取客户端配置”。 在新打开的页面,勾选“SDK文件”,SDK配置参数如下: 参数 值 链代码名称 chaincode 说明: 链代码名称需要和链代码安装&实例化时的一致。 证书存放路径 /root/gosdkdemo/config 通道名称 channel 组织&Peer节点 保持系统默认 勾选“共识节点证书”。 勾选“Peer节点证书”,指定节点组织选择organization,勾选“管理员证书”。 单击“下载”。下载SDK配置文件、orderer组织的管理员证书和organization组织的管理员证书。
  • 常用API接口 Fabric-sdk-go的主要入口是FabricSDK类,这个可以通过NewSDK()方法分别可以生成。 Fabric-sdk-go的常用操作基本都可以用这四个client实现:FabricClient,ChannelClient,ChannelMgmtClient,ResourceMgmtClient。 FabricSDK FabricSDK在pkg\fabsdk\fabsdk.go中,通过New ()方法生成object。New ()方法支持可变参数Option,以下是生成FabricSDK的例子: var opts []fabsdk.Option opts = append(opts, fabsdk.WithOrgid(org)) opts = append(opts, fabsdk.WithUserName("Admin")) sdk, err = fabsdk.New(config.FromFile(configFile), opts...) configFile是SDK配置文件的路径。OrgId是SDK配置文件中的组织id。 FabricSDK在def/fabapi/fabapi.go中,通过NewSDK()方法生成object。NewSDK()方法有一个Options参数,以下是生成Options参数的例子: deffab.Options{ConfigFile: configFile, LoggerFalogging.LoggerProvider(), UserName: sysadmin} ConfigFile是SDK配置文件的路径。LoggerFactory是可选的,不提供的话default会log到console。 FabricClient FabricClient主要有以下常用的接口。 接口名称 描述 参数值 返回值 CreateChannel 创建Channel的接口,用于创建channel。 request CreateChannelRequest txn.TransactionID, error QueryChannelInfo 查询Channel的接口,用于查询Channel的信息。 name string, peers []Peer Channel, error InstallChaincode 安装链码的接口,安装链码到区块链中。 request InstallChaincodeRequest []*txn.TransactionPropos lResponse, string, error InstallChaincode 安装链码的接口,安装链码到区块链中。 request InstallChaincodeRequest []*txn.TransactionPropos lResponse, string, error QueryChannels 查询channel的接口,查询区块链中已创建的通道。 peer Peer *pb.ChannelQueryResponse, error QueryInstalledChaincodes 查询已安装链码的接口,查询区块链中已安装的链码。 peer Peer *pb.ChaincodeQueryResponse, error ChannelClient ChannelClient主要包括链码查询和链码调用两类接口。 接口名称 描述 参数值 返回值 Query 链码查询接口,调用链码进行查询。 request QueryRequest []byte, error QueryWithOpts 带options的链码查询接口,与Query类似,但是可以通过QueryOpts指定notifier, peers,和timeout。 request QueryRequest, opt QueryOpts []byte, error ExecuteTx 链码调用接口,用于链码的调用。 request ExecuteTxRequest TransactionID, error ExecuteTxWithOpts 带options的链码调用接口,与ExecuteTx类似,但是可以通过ExecuteTxOpts指定notifier, peers,和timeout。 request ExecuteTxRequestopt ExecuteTxOpts TransactionID, error ChannelMgmtCLient ChannelMgmtClient 只有两个接口SaveChannel(req SaveChannelRequest) error 和SaveChannelWithOpts(req SaveChannelRequest, opts SaveChannelOpts) error 这两个接口是用于创建channel用的,这两个接口里面具体实现会调用到FabricClient里createChannel()接口。 ResourceMgmtClient ResourceMgmtClient主要就是与链码生命周期相关的接口和一个peer加入通道的接口。 链码的删除接口为 BCS 增加的接口,目前只实现了删除链码安装包的功能。 接口名称 描述 参数值 返回值 InstallCC 安装链码,用于安装链码。 reqInstallCCRequest []InstallCCResponse, error InstallCCWithOpts 带options的链码安装,与InstallCC类似,但是可以通过InstallCCOpts指定peers。 reqInstallCCRequest,opts InstallCCOpts []InstallCCResponse, error InstantiateCC 实例化链码接口,用于实例化链码。 channelID string,reqInstantiateCCRequest error InstantiateCCWithOpts 带options的链码实例化,与InstantiateCC类似,但是可以通过InstantiateCCOpts指定peers和timeout。 channelID string,reqInstantiateCCRequest, optsInstantiateCCOpts error UpgradeCC 升级链码,用于链码的升级。 channelID string,reqUpgradeCCRequest error UpgradeCCWithOpts 带options的链码升级,与UpgradeCC类似,但是可以通过UpgradeCCOpts指定peers和timeout。 channelID string,reqUpgradeCCRequest, optsUpgradeCCOpts error DeleteCC 删除链码,用于链码的删除,目前只有删除安装包的功能。 channelID string,reqDeleteCCRequest error DeleteCCWithOpts 带options的链码删除,与DeleteCC类似,但是可以通过DeleteCCWithOpts指定peers和timeout。 channelID string,reqDeleteCCRequest,opts DeleteCCOpts error JoinChannel Peers加入Channel的接口,用于peers加入Channel。 channelID string error JoinChannelWithOpts 带options的Peers加入Channel的接口,与JoinChannel类似,但是可以通过JoinChannelOpts指定peers。 channelID string,optsJoinChannelOpts error 带options的接口都可以指定peers,peers可通过def/fabapi/pkgfactory.go 里的NewPeer(userName string, orgName string, url string, certificate string, serverHostOverride string, config config.Config) (fab.Peer, error) 生成。这个method比原生的NewPeer多两个参数userName, orgName, 这两个参数用于peer双向tls找到对应的tls证书。
  • ValidateInitBalance 接口原型 func ValidateInitBalance(BalanceInfo, PubKey string) (InitBalance string, err error) 功能描述 校验sdk.InitBalance生成的balanceinfo中余额证明的有效性。 输入说明 参数名 类型 描述 是否必须 BalanceInfo string 初始余额数据 是 Pubkey string 余额加密的公钥信息 是 输出说明 参数名 类型 描述 是否必须 InitBalance string 初始余额密文 是 err error 错误信息 是 处理说明 验证余额有效后,返回余额的密文。 注意事项 这里用户余额真实性由用户的app逻辑保证,Chaincode端无法验证该用户的真实金额,只能验证该金额是大于0的范围。
  • ValidateTxInfo 接口原型 ValidateTxInfo(txInfo, cipherBalanceA, cipherBalanceB string) (newCipherBalanceA,newCipherBalanceB,newCipherTxA,newCipherTxB string,err error) 功能描述 校验PrepareTxInfo生成的Txinfo中交易证明的有效性。 输入说明 参数名 类型 描述 是否必须 txinfo string 交易证明数据 说明: 交易信息数据包含有交易密文数据和交易证明数据,该信息来源于sdk.PrepareTxInfo返回的txinfo信息。 是 cipherBalanceA string A当前的交易余额(密文) 是 cipherBalanceB string B当前的交易余额(密文) 是 输出说明 参数名 类型 描述 newCipherBalanceA string 交易后待更新的A的余额 newCipherBalanceB string 交易后待更新的B的余额 newCipherTxA string 交易金额(A的同态加密公钥加密) newCipherTxB string 交易金额(B的同态加密公钥加密) err error 错误 注意事项 这里A是转账方,B是收款方。
  • 功能介绍 可信数据交换基于分布式身份实现,参与数据交换的用户需要注册分布式身份,详细方法请参见分布式身份(公测)。 可信数据涉及两个主要数据结构:数据集和数据订单。数据集包括数据描述信息、访问控制信息(属性加密中的策略)等。数据订单包括数据申请、审核信息等。 可信数据交换支持三种模式:申请-授权、主动分享和细粒度访问控制。详细请参见模式介绍。 可信交换中的 数据加密 后支持多种存储服务,用户可以根据业务需要自己选择。调用者负责将密文数据存储到公开可访问的存储设备中。
  • 利用合约查询数据 查询请求消息构建 接口函数 func (msg *ContractRawMessage) BuildInvokeMessage(chainID string, name string, function string, args []string) (*common.RawMessage, error) 参数说明 参数 类型 说明 chainID string 链ID。 name string 合约名称。 function string 调用合约中的方法名。 args []string 合约方法参数。 返回值 类型 说明 *common.RawMessage 查询请求需发送的消息。 error 发送成功返回类型为nil,反之返回error。 查询请求消息发送。 接口函数 func (action *ContractAction) Invoke(rawMsg *common.RawMessage) (*common.RawMessage, error) 参数说明 参数 类型 说明 rawMsg *common.RawMessage 上述查询请求需发送的消息。 返回值 类型 说明 *common.RawMessage 查询请求返回的消息。 error 发送成功返回类型为nil,反之返回error。 父主题: Go SDK介绍
  • 简介 本指导文档主要针对具备Go/Java开发经验的人员进行开发指导,其中合约与应用程序需客户自行开发,整体开发流程如下: 本文档主要包含以下内容: 合约开发,Go语言、Java合约、Solidity合约。 SDK介绍,主要介绍Java、Golang语言SDK。 应用程序开发,介绍Java、Golang语言客户端开发流程与示例Demo。 开发流程中的其他操作,请参考: 华为云区块链实例购买 合约安装 下载配置文件 父主题: 华为云区块链引擎管理
  • 合约结构 AssemblyScript语言合约主要包括index.ts和contract.ts两个文件,其中index.ts为开发智能合约文件(contract.ts)依赖的合约SDK,合约涉及的业务相关开发仅在contract.ts文件,智能合约文件contract.ts需要根据实际业务进行开发。 合约SDK(index.ts)主要结构如下: // 引入智能合约文件 import { invoke, init } from "./contract";// 合约的初始化(wasm_init)接口。包含合约文件的init()接口,合约启动时,需要首先执行且只需要执行一次的逻辑放到合约文件init()接口中。export function wasm_init(buffer_offset: i32, size: i32):void{ // 实际调用合约文件的init()接口} // 合约被调用(wasm_invoke)接口。包含合约文件的invoke()接口,供合约使用者通过SDK的wasm_invoke接口调用。export function wasm_invoke(buffer_offset: i32, size: i32):void{ // 实际调用合约文件的invoke()接口}// 合约被调用(wasm_prepare)接口,保持为空即可。export function wasm_prepare():void{} 智能合约文件(contract.ts)主要结构如下: // 引入合约SDK方法 import { FuncName, smlog, Str2ArrayBuffer, Parameters, PutKV, ArrayBuffer2Str, GetKV, DelKV, MakeErrRes,MakeSuccessRes, Response,IteratorNew, IteValue, IteKey, IteNext, IteratorFree } from "./index"// 智能合约的初始化(init)接口的实现。export function init(txid:string):Response{}// 智能合约被调用(invoke)接口的实现。export function invoke(txid:string):Response{} 父主题: Wasm合约开发(AssemblyScript)
  • Init初始化余额 当用户注册成功后,需要初始化该用户的余额,默认为0。 输入说明 参数名 类型 描述 是否必须 PubKey string 公钥 是 Balance string 初始金额 是 处理 调用ValidateInitBalance,校验balance范围有效性,完成余额背书。 PubKey := string(args[0])BalanceInfo := string(args[1]) //PubKey := string(args[2])hashPubkey, err := t.calcAddr(PubKey)logger.Debug("encrypt initial balance")//validate balancecipherBalance,err := pswapi_cc.ValidateInitBalance(BalanceInfo,PubKey) if err != nil { logger.Error("fail to Validate InitBalance ") return shim.Error("fail toValidate InitBalance") } 输出说明 参数名 类型 描述 newCipherBalance string 余额密文
  • Transfer转账 输入说明 参数名 类型 描述 是否必须 AddrA string A-转账者地址 是 AddrB string B-收账者地址 是 txinfo String 交易信息PrepareTxInfo 是 处理说明 根据账户地址获取账本中A,B的当前余额cipherBalanceAKeyABlock, cipherBalanceBKeyBBlock。 校验证明有效性。 newCipherBalanceA,newCipherBalanceB,newCipherTxA,newCipherTxB, err := pswapi_cc.ValidateTxInfo(txInfo, cipherBalanceAKeyABlock, cipherBalanceBKeyBBlock) if err != nil { logger.Error("fail to validate trans information") return shim.Error("fail to validate trans information") } 输出更新后的余额(密文) 业务的账本内容需要用户定制,将上面加密的金额合入到用户的账本中保存,demo中定义了一个存储结构,保存完后通过json序列化为一个交易记录对象进行保存。 type TransRecord struct { FromAddr string ToAddr string TXType string Balance string TX string remark string }
  • Add 接口原型 func Add(cipher1, cipher2 string) (cipher string, err error) 功能描述 同态加法。 输入说明 参数名 类型 描述 是否必须 cipher1 string 被加密的密文1 是 cipher2 string 被加密的密文2 是 输出说明 参数名 类型 描述 cipher string 相加后的数据 err error 返回错误 注意事项 无。
  • PrepareTxInfo 接口原型 func PrepareTxInfo(cipherBalanceA string, transNumStr string, pubKeyA, pubKeyB string, privKeyA string,pwd string) (string, error) 功能描述 交易准备。 输入说明 参数名 类型 描述 是否必须 cipherBalanceA string A的当前余额(密文),取链上当前A的余额 是 transNumStr string 转账金额(明文) 是 pubKeyA string A的公钥串 是 pubKeyB string B的公钥串 是 PrivKeyA string A的私钥串 是 pwd string 用于加密保护的字符串 否 输出说明 参数名 类型 描述 Txinfo string 交易准备数据 err error 返回错误 注意事项 无。
  • InitBalance 接口原型 func InitBalance(balanceStr string, pubKey string) (string, error) 功能描述 初始化余额。 输入说明 参数名 类型 描述 是否必须 pubKey string 公钥串 是 balanceStr string 初始余额,只支持大于等于0的正整数,如果数字有小数,需要扩大倍数传入 是 输出说明 参数名 类型 描述 balanceInfo string 交易金额信息 err error 返回错误 注意事项 无。
  • Encypt 接口原型 func Encypt (secretNumStr string, pubKeyStr string) (ciphertext string, err error) 功能描述 同态加密。 输入说明 参数名 类型 描述 是否必须 secretNumStr string 需要加密的数值,只支持大于等于0的正整数,如果数字有小数,需要扩大倍数传入。 是 pubKeyStr String 同态加密的公钥 是 输出说明 参数名 类型 描述 ciphertext string 加密后的数据 err error 返回错误 注意事项 无。
  • Decrypt 接口原型 func Decrypt(ciphertext string, privKeyStr string, pwd string) (plainText *big.Int, err error) 功能描述 同态解密。 输入说明 参数名 类型 描述 是否必须 ciphertext string 需要解密的密文 是 privKeyStr string 同态加密的私钥串(被pwd加密保护 是 pwd string 用于保护私钥的字符串 否 输出说明 参数名 类型 描述 plainText *big.int 解密后的数据 err error 返回错误 注意事项 无。
  • 附录 fabric-sdk-client/go依赖的第三方包列表: 序号 包名 1 github.com/Knetic/govaluate 2 github.com/VividCortex/gohistogram 3 github.com/cloudflare/cfssl 4 github.com/go-kit/kit 5 github.com/golang/mock 6 github.com/golang/protobuf 7 github.com/hashicorp/hcl 8 github.com/hyperledger/fabric-config 9 github.com/hyperledger/fabric-lib-go 10 github.com/hyperledger/fabric-protos-go 11 github.com/magiconair/properties 12 github.com/miekg/pkcs11 13 github.com/mitchellh/mapstructure 14 github.com/pelletier/go-toml 15 github.com/pkg/errors 16 github.com/prometheus/client_golang 17 github.com/spf13/afero 18 github.com/spf13/cast 19 github.com/spf13/jwalterweatherman 20 github.com/spf13/pflag 21 github.com/spf13/viper 22 github.com/stretchr/testify 23 github.com/tjfoc/gmsm 24 google.golang.org/grpc 25 gopkg.in/yaml.v2 父主题: 国密加密
  • 部署应用 下载SDK和证书。 在“实例管理”页面,选择“Hyperledger Fabric增强版”页签,单击对应实例卡片上的“获取客户端配置”。 勾选“SDK文件”,SDK配置参数如下: 参数名称 说明 链代码名称 chaincodedemo 证书存放路径 /home/user/gatewayjavademo/config 通道名称 channel 组织&Peer节点 选择通道中所有节点组织 勾选“共识节点证书”。 勾选“Peer节点证书”,指定节点组织选择organization,勾选“管理员证书”。 单击“下载”,下载SDK配置文件、demo-orderer组织的管理员证书和organization组织的管理员证书。 复制并解压。 先下载工程源代码gatewayjavademo.zip文件并解压。 获取方法:登录区块链服务管理控制台,进入“应用案例”,在“Java示例Demo-Java SDK Demo”下方,单击“App_Gateway_Java_Demo”中Java项目源码的“下载”按钮。 将1步骤中的zip文件解压,把configs文件夹中的orderer文件夹、peer文件夹、sdk-config.json、sdk-config.yaml文件全部复制到gatewayjavademo目录下的config目录下。然后再将gatewayjavademo目录压缩成gatewayjavademo.zip包。 部署应用。 将新压缩的gatewayjavademo工程源代码gatewayjavademo.zip文件上传到CloudIDE开发环境中。 CloudIDE编译工程如下所示: 打开工程后等待一会,会自动下载工程依赖的包,然后按下图操作执行Run,就会得到预期结果。 gatewayjavademo工程中config目录下demo-channel-sdk-config.yaml文件,必须与gatewayjavademo/src/main/java/handler/Main.java和MainForMultiTask文件中helper.setConfigCtx("config/demo-channel-sdk-config.yaml")代码路径相同,保证可以正常运行Main.java。 客户端app交易的时候,如果指定了未实例化的组织和peer,那么首次交易会超时失败,请您重新运行即可正常交易。 每次成功执行Main.java,将会执行basicTransactionSample、commitListenerSample、contractListenerSample、blockListenerSample四个方法,向区块链存入多对键值对;可以通过区块链浏览器可以查看交易记录。
  • 准备工作 开通CloudIDE(或者用户自己准备JDK、maven和eclipse/IntelliJ IDEA)。 CloudIDE是软件开发生产线 CodeArts的云端开发环境服务,向开发者提供按需配置、快速获取的工作空间(包含编辑器和运行环境)。 在CloudIDE上创建一个空的Java工程,如图1所示。 图1 CloudIDE上创建一个空的Java工程 下载Java SDK示例源码,获取方法:登录区块链服务管理控制台,进入“应用案例”,在“Java示例Demo-Java SDK Demo”下方,单击“App_Gateway_Java_Demo”中Java项目源码的“下载”按钮。 购买区块链实例、安装链代码及实例化链代码操作,请参见《快速入门》。
  • 概述 用户的应用程序通过链代码与账本数据进行交互。应用程序开发可使用的语言比较广泛,如Golang、Solidity、Java、C++、Python、Node.js等。应用程序和链代码开发语言无强对应关系,只要应用程序能通过SDK来调用链代码即可。 Hyperledger Fabric增强版对应用程序开放的接口均为gRPC协议,与开源版本保持一致,通常使用SDK进行调用,详情可参考Hyperledger Fabric增强版SDK接口定义。 Java语言,请参考Java SDK使用指导。 Python语言,请参考Python使用指导。 Node.js语言,请参考Node.js SDK使用指导。 Go语言,请参考Go SDK使用指导。 父主题: 应用程序开发
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全