脚手架 TypeScript Chaincode Project

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.tscontroller.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:接受 CONCATHASH 的值。如果指定了 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 方案对象。在以下示例中,supplierIdrawMaterialSupply 分别为 stringnumber 类型,因此将类似类型和正确顺序的 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 类继承。
此方法返回介于 startIdendId 之间的资产列表。此方法在内部调用超级账本架构 getStateByRange 方法。
如果未提供 modelName 参数,则该方法返回 Promise<Object [ ] >。如果提供了 modelName 参数,则该方法将处理强制转换为调用方 Model 类型的操作。在以下示例中,结果数组的类型为 Supplier。如果从分类账返回的资产不是 Model 类型,则该资产将不包括在列表中。此检查由 Model 类中的只读 assetType 属性完成。
要返回 startIdendId 范围之间的所有资产,请使用通用控制器方法 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 类继承。
此方法返回介于 startIdendId 之间的资产列表。此方法在内部调用超级账本架构 getStateByRangeWithPagination 方法。
如果未提供 modelName 参数,则该方法返回 Promise<Object [ ] >。如果提供了 modelName 参数,则该方法将处理强制转换为调用方 Model 类型的操作。在以下示例中,结果数组的类型为 Supplier。如果从分类账返回的资产不是 Model 类型,则该资产将不包括在列表中。此检查由 Model 类中的只读 assetType 属性完成。
要返回按页面大小和书签筛选的 startIdendId 范围之间的所有资产,请使用通用控制器方法 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[ ] - 将基于其形成组合键的属性。
返回:
  • string - 返回组合键。
getByCompositeKey
此方法返回在创建组合键时与属性参数中提供的键和列匹配的资产。indexOfId 参数指示存根方法 SplitCompositeKey 的数组中返回的键的索引。在内部,此方法调用 Hyperledger Fabric 的 getStateByPartialCompositeKeysplitCompositeKeygetState 方法。
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
参数:
返回:
  • string - 返回通道 ID。
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
参数:
返回:
  • string - 返回调用身份的 MSP ID。
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;
}

然后,您可以使用此方法来初始化任何应用程序状态。