Blockchain App Builder 从您的规范文件中获取输入,并生成一个功能齐全的链码项目。该项目包含自动生成的类和函数,CRUD 方法,SDK 方法,参数自动验证,编组/非编组和透明持久性能力 (ORM)。
如果链代码项目使用 TypeScript 语言,则支架式项目包含三个主文件:
main.ts
<chaincodeName>.model.ts
<chaincodeName>.controller.ts
安装并打包所有必需的磁带库。
tsconfig.json
文件包含编译和构建 TypeScript 项目所需的配置。
model
子目录中的 <chaincodeName>.model.ts
文件包含多个资产定义,controller
子目录中的 <chaincodeName>.controller.ts
文件包含资产行为和 CRUD 方法。
model.ts
和 controller.ts
中的装饰器支持参数自动验证、参数的编集/解编集、透明持久性功能 (Transparent Persistent Function,ORM) 以及调用富查询等功能。
模型
每个模型类都扩展了 OchainModel
类,该类具有一个称为 assetType
的附加只读属性。此属性可用于仅提取此类型的资产。在创建和更新资产期间将忽略对此属性所做的任何更改。缺省情况下,属性值为 <modelName>
。
OchainModel
类对类的属性强制执行装饰器行为。
@Id('supplierId')
export class Supplier extends OchainModel<Supplier> {
public readonly assetType = 'supplier';
@Mandatory()
@Validate(yup.string())
public supplierId: string;
修饰器
-
类装饰器
@Id(identifier)
- 此装饰器标识唯一定义基础资产的属性。此属性用作记录的键,该键表示处于链代码状态的此资产。当安装了新的 TypeScript 项目时,将自动应用此装饰器。装饰器的
identifier
参数从规范文件中获取值。@Id('supplierId')
export class Supplier extends OchainModel{
...
}
-
属性装饰器
- 可以使用多个属性装饰器。装饰器按从上到下的顺序进行解析。
@Mandatory()
- 此装饰器将以下属性标记为必需属性,因此在保存到分类账时无法跳过该属性。如果跳过,则会引发错误。
@Mandatory()
public supplierID: string;
@Default(param)
- 此装饰器指示以下属性具有默认值。在将属性保存到分类账时跳过该属性时,将使用参数 (
param
) 中的默认值。@Default('open for business')
@Validate(yup.string())
public remarks: string;
@Validate(param)
- 此装饰器后面的属性将根据参数指定的模式进行验证。参数
param
采用 yup 方案,可以将多个方案方法链接在一起以添加复杂的验证。有关更多信息,请参见 https://www.npmjs.com/package/yup 。@Validate(yup.number().min(3))
public productsShipped: number;
@ReadOnly(param)
- 此属性装饰器将底层属性标记为具有只读值。参数中的值(例如 param)在将该属性保存在分类帐中时使用。设置值后,无法对其进行编辑或删除。
@ReadOnly('digicur')
public token_name: string;
@Embedded(PropertyClass)
- 此属性装饰器将底层属性标记为可嵌入资产。它将可嵌入类作为参数。此类必须扩展
EmbeddedModel
类。此要求由装饰者验证。
- 在以下示例中,
Employee
类具有一个名为 address
、类型为 Address
的属性,该属性将嵌入到 Employee
资产中。这由 @Embedded()
装饰器表示。
export class Employee extends OchainModel<Employee> {
public readonly assetType = 'employee';
@Mandatory()
@Validate(yup.string())
public emplyeeID: string;
@Mandatory()
@Validate(yup.string().max(30))
public firstName: string;
@Mandatory()
@Validate(yup.string().max(30))
public lastName: string;
@Validate(yup.number().positive().min(18))
public age: number;
@Embedded(Address)
public address: Address;
}
export class Address extends EmbeddedModel<Address> {
@Validate(yup.string())
public street: string;
@Validate(yup.string())
public city: string;
@Validate(yup.string())
public state: string;
@Validate(yup.string())
public country: string;
}
- 创建
Address
类的新实例时,@Validate()
装饰器将自动验证 Address
类的所有属性。请注意,Address
类没有 assetType
属性或 @Id()
类装饰器。此资产及其属性不会单独保存在分类账中,而是与 Employee
资产一起保存。嵌入式资产是用户定义的类,用作值类型。此类的实例只能作为包含对象(OchainModel
资产)的一部分存储在分类账中。上述所有装饰器均基于输入文件自动应用,同时支架项目。
@Derived(STRATEGY, ALGORITHM, FORMAT)
- 此装饰器用于定义从其他属性派生的属性。此装饰器有两个必备参数:
STRATEGY
:接受 CONCAT
或 HASH
的值。如果指定了 HASH
,则需要附加参数 ALGORITHM
。缺省算法为 sha256
;还支持 md5
。
FORMAT
:接受要由策略使用的规范字符串和值的数组。
@Id('supplierID')
export class Supplier extends OchainModel<Supplier> {
public readonly assetType = 'supplier';
@Mandatory()
@Derived(STRATEGY.HASH.'sha256',['IND%1IND%2','license','name'])
@Validate(yup.string())
public supplierID: string;
@Validate(yup.string().min(2).max(4))
public license: string;
@Validate(yup.string().min(2).max(4))
public name: string;
-
方法装饰器
@Validator(…params)
- 此装饰器应用于主控制器类的方法。此装饰器对于解析参数、验证所有属性装饰器以及返回模型/类型对象非常重要。控制器方法必须具有此装饰器才能调用。它将多个用户创建的模型或 yup 方案作为参数。
- 参数的顺序必须与方法中参数的顺序完全相同。
- 在以下示例中,在与方法参数中的
asset
类型相对应的参数中传递 Supplier
模型引用。在运行时,装饰器将方法参数解析并转换为 JSON 对象,对 Supplier
验证器进行验证,成功验证后将 JSON 对象转换为 Supplier
对象并将其分配给 asset
变量。然后最终调用底层方法。@Validator(Supplier)
public async createSupplier(asset: Supplier) {
return await this.Ctx.Model.save(asset);
}
- 在以下示例中,传递了多个资产引用;它们对应于方法参数的对象类型。请注意参数的顺序。
@Validator(Supplier, Manufacturer)
public async createProducts(supplier: Supplier, manufacturer: Manufacturer) {
}
- 除了资产引用外,如果参数为基本类型,还可以传递 yup 方案对象。在以下示例中,
supplierId
和 rawMaterialSupply
分别为 string
和 number
类型,因此将类似类型和正确顺序的 yup 方案传递给装饰器。请注意 yup 方案方法的链。@Validator(yup.string(), yup.number().positive())
public async fetchRawMaterial(supplierID: string, rawMaterialSupply: number) {
const supplier = await this.Ctx.Model.get(supplierID, Supplier);
supplier.rawMaterialAvailable = supplier.rawMaterialAvailable + rawMaterialSupply;
return await this.Ctx.Model.update(supplier);
}
ORM
在上下文 (Ctx
) 对象的 Model
类中捕获透明持久性功能或简化 ORM。如果您的模型调用了以下任一 SDK 方法,请使用 this.Ctx.Model
访问它们。
以下 SDK 方法实现 ORM:
save
调用 Hyperledger Fabric putState
方法。
get
调用 Hyperledger Fabric getState
方法。
update
调用 Hyperledger Fabric putState
方法。
delete
调用 Hyperledger Fabric deleteState
方法。
history
调用 Hyperledger Fabric getHistoryForKey
方法。
getByRange
调用 Hyperledger Fabric getStateByRange
方法。
getByRangeWithPagination
调用 Hyperledger Fabric getStateByRangeWithPagination
方法。
有关更多信息,请参见:
SDK Methods 。
SDK 方法
注意:
从版本 21.3.2 开始,访问 ORM 方法的方式已发生变化。运行
ochain --version
命令以确定 Blockchain App Builder 的版本。
在以前的发行版中,ORM 方法是从 OchainModel
类继承的。在版本 21.3.2 和更高版本中,这些方法是在上下文 (Ctx
) 对象的 Model
类上定义的。要调用这些方法,请使用 this.Ctx.Model.<method_name>
访问它们。
以下示例显示了以前发行版中的方法调用:
@Validator(Supplier)
public async createSupplier(asset: Supplier){
return await asset.save();
}
以下示例显示了版本 21.3.2 及更高版本中的方法调用:
@Validator(Supplier)
public async createSupplier(asset: Supplier) {
return await this.Ctx.Model.save(asset);
}
升级到版本 21.3.2 后,请在使用早期版本的 Blockchain App Builder 创建的所有链代码项目中进行此更改。如果使用 sync
命令同步规范文件与源代码之间的更改,这些更改将自动带到控制器中,以便使用现成的方法。您仍需要手动解决任何冲突。
-
save
save
方法将调用方 asset
详细信息添加到分类账。
- 此方法在内部调用超级账本架构
putState
。所有编组/编组均在内部处理。save
方法是 Model
类的一部分,您可以使用 Ctx
对象访问该类。
-
Ctx.Model.save(asset: <Instance of Asset Class> , extraMetadata?: any) : Promise <any>
- 参数:
extraMetadata : any
(可选)- 用于将元数据与资产保存在分类账中之外。
- 返回:
Promise<any>
- 完成时返回 promise。
- 示例:
@Validator(Supplier)
public async createSupplier(asset: Supplier) {
return await this.Ctx.Model.save(asset);
}
-
get
get
方法是 OchainModel
类的方法,由 {chaincodeName}.model.ts
的具体模型类继承。get
方法是 Model
类的一部分,您可以使用 Ctx
对象访问该类。
- 要从给定
id
返回任何资产,请使用通用控制器方法 getAssetById
。
-
Ctx.Model.get(id: string, modelName: <Model Asset Class Name>) : Promise<asset>
- 参数:
id : string
- 用于将数据保存到分类账中的键。
modelName: <Model Asset Class Name>
-(可选)对要返回的资产分类进行建模。
- 返回:
Promise: <Asset>
- 如果未提供 modelName
参数且分类帐中存在数据,则返回 Promise<object>
。如果分类帐中不存在 id
参数,则会返回错误消息。如果提供了 modelName
参数,则返回类型为 <Asset>
的对象。即使从分类帐中返回具有给定 id
的任何资产,此方法也会处理转换到调用方 Asset
类型。如果从分类账返回的资产不是 Asset
类型,则该方法将引发错误。此检查由 Model
类中的只读 assetType
属性完成。
- 示例:
@Validator(yup.string())
public async getSupplierById(id: string) {
const asset = await this.Ctx.Model.get(id, Supplier);
return asset;
}
在示例中,asset
的类型为 Supplier
。
-
update
update
方法更新分类账中的调用方 asset
详细信息。此方法返回 promise。
- 此方法在内部调用超级账本架构
putState
。所有编组/编组均在内部处理。update
方法是 Model
类的一部分,您可以使用 Ctx
对象访问该类。
-
Ctx.Model.update(asset: <Instance of Asset Class> , extraMetadata?: any) : Promise <any>
- 参数:
extraMetadata : any
(可选)- 用于将元数据与资产保存在分类账中之外。
- 返回:
Promise<any>
- 完成时返回 promise。
- 示例:
@Validator(Supplier)
public async updateSupplier(asset: Supplier) {
return await this.Ctx.Model.update(asset);
}
-
delete
- 这将从
id
提供的分类账中删除资产(如果存在)。此方法在内部调用超级账本架构 deleteState
方法。delete
方法是 Model
类的一部分,您可以使用 Ctx
对象访问该类。
-
Ctx.Model.delete(id: string): Promise <any>
- 参数:
id : string
- 用于将数据保存到分类账的关键字。
- 返回:
Promise <any>
- 完成时返回 promise。
- 示例:
@Validator(yup.string())
public async deleteSupplier(id: string) {
const result = await this.Ctx.Model.delete(id);
return result;
}
-
history
history
方法是 Model
类的一部分,您可以使用 Ctx
对象访问该类。此方法从分类账中返回 id
提供的资产历史记录(如果存在)。
- 此方法在内部调用超级账本架构
getHistoryForKey
方法。
-
Ctx.Model.history(id: string): Promise <any>
- 参数:
id : string
- 用于将数据保存到分类账的关键字。
- 返回:
Promise <any[]>
- 完成时返回任何 []。
- 范例
@Validator(yup.string())
public async getSupplierHistoryById(id: string) {
const result = await this.Ctx.Model.history(id);
return result;
}
getSupplierHistoryById
的返回资产历史记录示例:[
{
"trxId": "8ef4eae6389e9d592a475c47d7d9fe6253618ca3ae0bcf77b5de57be6d6c3829",
"timeStamp": 1602568005,
"isDelete": false,
"value": {
"assetType": "supplier",
"supplierId": "s01",
"rawMaterialAvailable": 10,
"license": "abcdabcdabcd",
"expiryDate": "2020-05-28T18:30:00.000Z",
"active": true
}
},
{
"trxId": "92c772ce41ab75aec2c05d17d7ca9238ce85c33795308296eabfd41ad34e1499",
"timeStamp": 1602568147,
"isDelete": false,
"value": {
"assetType": "supplier",
"supplierId": "s01",
"rawMaterialAvailable": 15,
"license": "valid license",
"expiryDate": "2020-05-28T18:30:00.000Z",
"active": true
}
}
]
-
getByRange
getByRange
方法是 OchainModel
类的静态方法,由 {chaincodeName}.model.ts
的具体 Model
类继承。
- 此方法返回介于
startId
和 endId
之间的资产列表。此方法在内部调用超级账本架构 getStateByRange
方法。
- 如果未提供
modelName
参数,则该方法返回 Promise<Object [ ] >
。如果提供了 modelName
参数,则该方法将处理强制转换为调用方 Model
类型的操作。在以下示例中,结果数组的类型为 Supplier
。如果从分类账返回的资产不是 Model
类型,则该资产将不包括在列表中。此检查由 Model
类中的只读 assetType
属性完成。
- 要返回
startId
和 endId
范围之间的所有资产,请使用通用控制器方法 getAssetsByRange
。
-
Ctx.Model.getByRange(startId: string, endId: string, modelName: <Asset Model Class Name> ): Promise <any>
- 参数:
startId : string
- 范围的起始键,该键包含在范围中。
endId : string
- 该范围的结束键,该键被排除在范围之外。
modelName: <Model Asset Class Name>
-(可选)对要返回的资产分类进行建模。
- 返回:
Promise< Asset[ ] >
- 完成时返回 <Asset>
的数组。
- 示例:
@Validator(yup.string(), yup.string())
public async getSupplierByRange(startId: string, endId: string) {
const result = await this.Ctx.Model.getByRange(startId, endId, Supplier);
return result;
}
-
getByRangeWithPagination
getByRangeWithPagination
方法是 OchainModel
类的静态方法,由 {chaincodeName}.model.ts
的具体 Model
类继承。
- 此方法返回介于
startId
和 endId
之间的资产列表。此方法在内部调用超级账本架构 getStateByRangeWithPagination
方法。
- 如果未提供
modelName
参数,则该方法返回 Promise<Object [ ] >
。如果提供了 modelName
参数,则该方法将处理强制转换为调用方 Model
类型的操作。在以下示例中,结果数组的类型为 Supplier
。如果从分类账返回的资产不是 Model
类型,则该资产将不包括在列表中。此检查由 Model
类中的只读 assetType
属性完成。
- 要返回按页面大小和书签筛选的
startId
到 endId
范围之间的所有资产,请使用通用控制器方法 getAssetsByRange
。
-
public async getByRangeWithPagination<T extends OchainModel<T>>(startId: string, endId: string, pageSize: number, bookmark?: string, instance?: new (data: any, skipMandatoryCheck: boolean, skipReadOnlyCheck: boolean) => T): Promise<T[]>
- 参数:
startId : string
- 范围的起始键,该键包含在范围中。
endId : string
- 该范围的结束键,该键被排除在范围之外。
pageSize : number
- 查询的页面大小。
bookmark : string
- 查询的书签。输出从此书签开始。
modelName: <Model Asset Class Name>
-(可选)对要返回的资产分类进行建模。
- 返回:
Promise< Asset[ ] >
- 完成时返回 <Asset>
的数组。
-
getId
- 当资产的派生关键字为
Id
时,可以使用此方法获取派生 ID。如果派生关键字包含 %t
(时间戳),此方法将返回错误。
- 参数:
object
- 对象必须包含派生密钥所依赖的所有属性。
- 返回:
- 示例:
@Validator(yup.string(), yup.string())
public async customGetterForSupplier(license: string, name: string){
let object = {
license : license,
name: name
}
const id = await this.Ctx.Model.getID(object);
return this.Ctx.Model.get(id);
}
有关令牌 SDK 方法,请参见 Tokenization Support Using Blockchain App Builder 下的主题。
控制器
主控制器类扩展了 OchainController
类。只有一个主控制器。
export class TSProjectController extends OchainController{
您可以创建任意数量的类、函数或文件,但只能从外部调用在主控制器类中定义的那些方法;其余的方法将被隐藏。
自动生成的方法
如 Input Specification File 中所述,您可以指定要在规范文件中生成的 CRUD 方法。例如,如果指定生成所有方法,则结果将类似于以下代码:
@Validator(Supplier)
public async createSupplier(asset: Supplier) {
return await this.Ctx.Model.save(asset);
}
@Validator(yup.string())
public async getSupplierById(id: string) {
const asset = await this.Ctx.Model.get(id, Supplier);
return asset;
}
@Validator(Supplier)
public async updateSupplier(asset: Supplier) {
return await this.Ctx.Model.update(asset);
}
@Validator(yup.string())
public async deleteSupplier(id: string) {
const result = await this.Ctx.Model.delete(id);
return result;
}
@Validator(yup.string())
public async getSupplierHistoryById(id: string) {
const result = await this.Ctx.Model.history(id);
return result;
}
@Validator(yup.string(), yup.string())
public async getSupplierByRange(startId: string, endId: string) {
const result = await this.Ctx.Model.getByRange(startId, endId, Supplier);
return result;
}
控制器方法详细信息
除了以前的模型 CRUD 和非 CRUD 方法外,Blockchain App Builder 还为以下超级账本架构方法提供控制器随时可用的支持:
getAssetById
getAssetsByRange
getAssetHistoryById
query
queryWithPagination
generateCompositeKey
getByCompositeKey
getTransactionId
getTransactionTimestamp
getChannelID
getCreator
getSignedProposal
getArgs
getStringArgs
getMspID
getNetworkStub
注意:
这些方法适用于扩展
OChainController
类的任意类中的
this
上下文。
例如:
public async getModelById(id: string) {
const asset = await this.getAssetById(id);
return asset;
}
@Validator(yup.string(), yup.string())
public async getModelsByRange(startId: string, endId: string) {
const asset = await this.getAssetsByRange(startId, endId);
return asset;
}
public async getModelHistoryById(id: string) {
const result = await this.getAssetHistoryById(id);
return result;
}
-
getAssetById
getAssetById
方法基于指定的 ID 返回资产。这是一个通用方法,可用于获取任何类型的资产。
this.getAssetById(id: string): Promise<byte[]>
- 参数:
id : string
- 用于将数据保存到分类账的关键字。
- 返回:
Promise <byte [ ]>
- 完成时返回 promise。必须将 byte[]
转换为对象。
-
getAssetsByRange
getAssetsByRange
方法返回从 startId
(含)到 endId
(不含)的所有资产,而不考虑资产类型。这是一个通用方法,可用于获取任何类型的资产。
this.getAssetsByRange(startId: string, endId: string):
Promise<shim.Iterators.StateQueryIterator>
- 参数:
startId : string
- 范围的起始键,该键包含在范围中。
endId : string
- 该范围的结束键,该键被排除在范围之外。
- 返回:
Promise< shim.Iterators.StateQueryIterator>
- 完成时返回迭代器。你必须迭代它。
-
getAssetHistoryById
getAssetHistoryById
方法返回指定 ID 的资产的历史记录迭代器。
this.getAssetHistoryById(id: string):
Promise<shim.Iterators.HistoryQueryIterator>
- 参数:
id : string
- 用于将数据保存到分类账的关键字。
- 返回:
Promise<shim.Iterators.HistoryQueryIterator>
- 返回历史记录查询迭代器。你必须迭代它。
-
query
query
方法对分类账运行丰富的 SQL/Couch 数据库查询。此方法仅适用于 Oracle Blockchain Platform 上的远程部署。这是对分类账运行 SQL 查询的通用方法。
this.query(queryStr: string):
Promise<shim.Iterators.StateQueryIterator>
- 参数:
queryStr : string
- 丰富的 SQL/Couch 数据库查询。
- 返回:
Promise<shim.Iterators.StateQueryIterator>
- 返回状态查询迭代器。你必须迭代它。
-
queryWithPagination
- 此方法对分类账运行丰富的 SQL/Couch 数据库查询,按页面大小和书签进行筛选。此方法仅适用于 Oracle Blockchain Platform 上的远程部署。这是对分类账运行 SQL 查询的通用方法。
-
public async queryWithPagination(query: string, pageSize: number, bookmark?: string)
- 参数:
query : string
- 丰富的 SQL/Couch 数据库查询。
pageSize : number
- 查询的页面大小。
bookmark : string
- 查询的书签。输出从此书签开始。
- 返回:
Promise<shim.Iterators.StateQueryIterator>
- 返回状态查询迭代器。你必须迭代它。
-
generateCompositeKey
- 此方法根据
indexName
和参数中提供的属性生成并返回组合键。
this.generateCompositeKey(indexName: string, attributes:
string[]): string
- 参数:
indexName : string
- 用于将数据保存到分类账的关键字的对象类型。
attributes: string[ ]
- 将基于其形成组合键的属性。
- 返回:
-
getByCompositeKey
- 此方法返回在创建组合键时与属性参数中提供的键和列匹配的资产。
indexOfId
参数指示存根方法 SplitCompositeKey
的数组中返回的键的索引。在内部,此方法调用 Hyperledger Fabric 的 getStateByPartialCompositeKey
、splitCompositeKey
和 getState
方法。
this.getByCompositeKey(key: string, columns: string[],
indexOfId: number): Promise<any []>
- 参数:
key: string
- 用于将数据保存到分类账的关键字。
columns: string[ ]
- 基于其生成密钥的属性。
indexOfId: number
- 要从键中检索的属性的索引。
- 返回:
Promise< any [ ]
- 完成时返回任何 []
。
-
getTransactionId
- 返回当前链代码调用请求的事务处理 ID。事务处理 ID 在渠道范围内唯一标识事务处理。
this.getTransactionId(): string
- 参数:
- 返回:
string
- 返回当前链代码调用请求的事务处理 ID。
-
getTransactionTimestamp
- 返回创建事务处理时的时间戳。这取自交易
ChannelHeader
,因此它将指示客户的时间戳,并在所有背书者中具有相同的值。
this.getTransactionTimestamp(): Timestamp
- 参数:
id : string
- 用于将数据保存到分类账的关键字。
- 返回:
Timestamp
- 返回创建事务处理的时间戳。
-
getChannelID
- 返回链代码要处理的建议的渠道 ID。
this.getChannelID(): string
- 参数:
- 返回:
-
getCreator
- 返回链代码调用的提交者的身份对象。
this.getCreator(): shim.SerializedIdentity
- 参数:
- 返回:
shim.SerializedIdentity
- 返回身份对象。
-
getSignedProposal
- 返回已签名事务处理建议的完全解码的对象。
this.getSignedProposal():
shim.ChaincodeProposal.SignedProposal
- 参数:
- 返回:
shim.ChaincodeProposal.SignedProposal
- 返回已签名事务处理建议的解码对象。
-
getArgs
- 从链代码调用请求中以字符串数组形式返回参数。
this.getArgs(): string[]
- 参数:
- 返回:
string [ ]
- 从链代码调用返回参数作为字符串数组。
-
getStringArgs
- 从链代码调用请求中以字符串数组形式返回参数。
this.getStringArgs(): string[]
- 参数:
- 返回:
string [ ]
- 从链代码调用返回参数作为字符串数组。
-
getMspID
- 返回调用身份的 MSP ID。
this.getMspID(): string
- 参数:
- 返回:
-
getNetworkStub
- 您可以通过调用此方法来访问 shim stub。这可以帮助您编写自己的实现,即直接处理资产。
this.getNetworkStub(): shim.ChaincodeStub
- 参数:
- 返回:
shim.ChaincodeStub
- 返回链代码网络存根。
-
invokeCrossChaincode
- 您可以在链代码中使用此方法来调用另一个链代码中的函数。两个链代码必须安装在同一对等点上。
-
this.invokeCrossChaincode(chaincodeName: string, methodName: string, args: string[], channelName: string): Promise<any>
- 参数:
chaincodeName
- 要调用的链代码的名称。
methodName
- 链代码中要调用的方法的名称。
arg
- 调用方法的参数。
channelName
- 要调用的链代码所在的渠道。
- 返回:
Promise<any>
- 返回包含三个字段的 JSON 对象:
isValid
- true
(如果调用有效)。
payload
- 跨链代码调用作为 JSON 对象返回的输出。
message
- 跨链代码调用返回的消息,采用 UTF-8 格式。
-
invokeChaincode
- 此方法调用另一个链代码中的函数。两个链代码必须安装在同一对等点上。
-
this.invokeChaincode(chaincodeName: string, methodName: string, args: string[], channelName: string): Promise<any>
- 参数:
chaincodeName
- 要调用的链代码的名称。
methodName
- 链代码中要调用的方法的名称。
arg
- 调用方法的参数。
channelName
- 要调用的链代码所在的渠道。
- 返回:
Promise<any>
- 返回包含三个字段的 JSON 对象:
isValid
- true
(如果调用有效)。
payload
- 跨链代码调用作为 JSON 对象返回的输出。
message
- 跨链代码调用返回的消息,采用 UTF-8 格式。
自定义方法
以下定制方法是从示例规范文件中生成的。
executeQuery
方法显示了如何调用 SQL 富查询。根据规范文件中指定的参数类型,Blockchain App Builder 会自动添加针对这些参数的验证器。
/**
*
* BDB sql rich queries can be executed in OBP CS/EE.
* This method can be invoked only when connected to remote OBP CS/EE network.
*
*/
@Validator(yup.string()}
public async executeQuery(query: string) {
const result = await OchainController.query(query);
return result;
}
@Validator(yup.string(), yup.number()}
public async fetchRawMaterial(supplierId: string, rawMaterialSupply: number) {
}
@Validator(yup.string(), yup.string(), yup.number())
public async getRawMaterialFromSupplier(manufacturerId: string, supplierId: string, rawMaterialSupply: number) {
}
@Validator(yup.string(), yup.number(), yup.number())
public async createProducts(manufacturerId: string, rawMaterialConsumed: number, productsCreated: number) {
}
public async sendProductsToDistribution() {
}
初始化方法
控制器中提供了具有空定义的定制 init
方法。如果您使用区块链应用构建器进行部署或升级,则会自动调用 init
方法。如果您从 Oracle Blockchain Platform 控制台部署或升级,则必须手动调用 init
方法。您可以使用第三方工具(如 Postman)手动调用 init
方法。
export class TestTsProjectController extends OchainController {
public async init(params: any) {
return;
}
然后,您可以使用此方法来初始化任何应用程序状态。