链代码事件

Blockchain App Builder 的增强版本可以为令牌操作生成链代码事件。

Chaincode 事件是运行事务处理时发出的特定通知。事件包括交易信息,这些信息可用于通知外部系统区块链账本状态的特定条件或更改。您可以使用链代码事件实现与不在区块链上的应用的实时集成和交互,并促进整个区块链环境中的事件驱动的工作流和监视。链代码事件有两个组成部分,即事件名称和有效负载。

所有区块链应用程序构建器规范文件都支持链代码事件。如果启用链代码事件,则脚手架项目中的所有控制器功能都将发出事件,但 getter 方法除外。例如,在标记方案中,当标记铸造、传输、刻录或锁定时,链代码事件将被发出

可以使用规范文件中的布尔 events 参数启用链代码事件,如以下示例中所示。

assets:
    - name: FiatMoneyTOK # Asset name
      type: token  # Asset type
      events: true  # Generate events for create, update and delete APIs

如果启用事件,则脚手架链代码项目中的控制器功能将包括事件创建方法,如以下示例所示。

TypeScript:

@Validator(yup.string(), yup.string(), yup.string())
public async createAccount(org_id: string, user_id: string, token_type: string) {
  await this.Ctx.Auth.checkAuthorization("ACCOUNT.createAccount", "TOKEN", { org_id });
  await this.Ctx.Model.createEvent(EVENT_NAME.CREATE_ACCOUNT, { org_id, user_id, token_type });
  return await this.Ctx.Account.createAccount(org_id, user_id, token_type);
}

开始:

func (t *Controller) CreateAccount(org_id string, user_id string, token_type string, daily_limits ...account.AccountDailyLimits) (interface{}, error) {
    auth, err := t.Ctx.Auth.CheckAuthorization("Account.CreateAccount", "TOKEN", map[string]string{"org_id": org_id})
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
    }
    err = t.Ctx.Model.CreateEvent(constants.CreateAccountEventName, map[string]interface{}{"org_id": org_id, "user_id": user_id, "token_type": token_type})
    if err != nil {
        return nil, err
    }
    return t.Ctx.Account.CreateAccount(org_id, user_id, token_type, daily_limits...)
}

链代码事件对名称和有效负载组件使用以下默认值。可以根据需要修改默认值。

EventName
控制器功能的名称。
有效负载
包含控制器函数的所有输入参数的 JSON 对象。

扩展的令牌分类框架和 ERC-1155 标准在令牌详细信息中包含一个 events 参数。如果规范文件中的 events 参数设置为 true,则生成的令牌中的 events 参数将设置为 true。如果规范文件中的 events 参数设置为 false 或未定义,则生成的标记中的 events 参数将设置为 false。以下示例显示了包含 TypeScript 和 Go 的新 events 参数的标记。

TypeScript:

{
    "metadata": {
        "paintingName": "monalisa",
        "description": "monalisa painting",
        "image": "image link",
        "painterName": "Leonardo da Vinci"
    },
    "assetType": "otoken",
    "events": true,
    "quantity": 1,
    "tokenId": "artnft",
    "tokenName": "artcollection",
    "tokenDesc": "artcollection nft",
    "tokenStandard": "erc1155+",
    "tokenType": "nonfungible",
    "tokenUnit": "whole",
    "behaviors": [
        "indivisible",
        "singleton",
        "mintable",
        "transferable",
        "burnable",
        "roles"
    ],
    "roles": {
        "minter_role_name": "minter",
        "burner_role_name": "burner"
    },
    "mintable": {
        "max_mint_quantity": 500
    },
    "owner": "oaccount~42e89f4c72dfde9502814876423c6da630d466e87436dd1aae201d347ad1288d",
    "createdBy": "oaccount~42e89f4c72dfde9502814876423c6da630d466e87436dd1aae201d347ad1288d",
    "creationDate": "2022-12-29T04:08:35.000Z",
    "isBurned": false,
    "tokenUri": "tu",
    "price": 10000,
    "onSaleFlag": false
}

开始:

{
    "AssetType": "otoken",
    "Behavior": [
        "indivisible",
        "singleton",
        "mintable",
        "transferable",
        "burnable",
        "roles"
    ],
    "CreatedBy": "oaccount~42e89f4c72dfde9502814876423c6da630d466e87436dd1aae201d347ad1288d",
    "CreationDate": "2022-12-29T09:57:03+05:30",
    "Events": true,
    "IsBurned": false,
    "Mintable": {
        "Max_mint_quantity": 500
    },
    "OnSaleFlag": false,
    "Owner": "oaccount~42e89f4c72dfde9502814876423c6da630d466e87436dd1aae201d347ad1288d",
    "Price": 100,
    "Quantity": 1,
    "Roles": {
        "burner_role_name": "burner",
        "minter_role_name": "minter"
    },
    "TokenDesc": "token description",
    "TokenId": "monalisa",
    "TokenMetadata": {
        "Description": "Mona Lisa Painting",
        "Image": "monalisa.jpeg",
        "PainterName": "Leonardo_da_Vinci",
        "PaintingName": "Mona_Lisa"
    },
    "TokenName": "artcollection",
    "TokenStandard": "erc1155+",
    "TokenType": "nonfungible",
    "TokenUnit": "whole",
    "TokenUri": "https://bafybeid6pmpp62bongoip5iy2skosvyxh3gr7r2e35x3ctvawjco6ddmsq\\\\ .ipfs.infura-ipfs.io/?filename=MonaLisa.jpeg"
}

生成活动

stub.setEvent 方法允许链代码在事务处理运行时创建和发出事件。以下代码显示了该方法的 TypeScript 版本。
async setEvent(eventName: string, payload: Buffer): Promise<void>

在此示例中,eventName 是要分配给事件的名称,payload 是与该事件关联的数据。有效负载可以包含要随事件一起发送的任何信息,通常采用 JSON 格式进行序列化。

批方法的链代码事件

增强的 ERC-1155 标准支持批处理方法。批处理方法对作为参数传递的多个令牌进行操作。对于批处理方法,链代码事件仅针对在规范文件中将 events 参数设置为 true 的标记发出。

对于在批处理方法中完成的每个事务处理,将生成相应的链代码事件。每个链代码事件的有效负载包含事务处理详细信息。例如,如果使用 BatchTransfer 方法传输五个不同标记的数量,则会发出五个对应的链代码事件。每个事件的有效负载包含标记详细信息和传输的数量,以及适用于所有批处理传输的通用参数。

以下示例显示了使用增强型 ERC-1155 标准的事件代码。
@Validator(yup.string(), yup.string(), yup.string(), yup.string(), yup.array().of(yup.string()), yup.array().of(yup.number()))
  public async batchTransferFrom(
    fromOrgId: string,
    fromUserId: string,
    toOrgId: string,
    toUserId: string,
    tokenIds: string[],
    quantity: number[]
  ) {
    const fromAccountId = this.Ctx.ERC1155Account.generateAccountId(fromOrgId, fromUserId, ACCOUNT_TYPE.USER_ACCOUNT);
    const toAccountId = this.Ctx.ERC1155Account.generateAccountId(toOrgId, toUserId, ACCOUNT_TYPE.USER_ACCOUNT);
    let tokenAssets = [];
    for (let i = 0; i < tokenIds.length; i++) {
      const tokenAsset = await this.Ctx.ERC1155Token.get(tokenIds[i]);
      tokenAssets.push(tokenAsset);
    }
    await this.Ctx.Model.createEventForBatch(EVENT_NAME.BATCH_TRANSFER_FROM, { fromOrgId, fromUserId, toOrgId, toUserId }, quantity, tokenAssets);
    return await this.Ctx.ERC1155Token.batchTransferFrom(fromAccountId, toAccountId, tokenIds, quantity);
  }

多个资产的链代码事件

增强的令牌分类框架和 ERC-1155 标准支持在规范文件中定义多个令牌资产。链代码事件行为因方法是特定于令牌(例如创建或更新令牌)还是通用(例如铸造或刻录)而异。

对于特定于令牌的方法,链代码事件仅针对在规范文件中将 events 参数设置为 true 的令牌生成。

对于常见方法,如果规范文件中有任何令牌的 events 参数设置为 true,则链代码事件将在基架项目中生成。实际链代码事件行为基于传递给方法的令牌 ID 参数的数量。

  • 如果将单个令牌 ID 作为参数传递,则仅当相应令牌详细信息中的 events 参数设置为 true 时才会生成链代码事件。
  • 如果将多个标记 ID 作为参数传递,则仅当任一标记详细信息中的 events 参数设置为 true 时才会生成链代码事件。
  • 如果未将标记 ID 作为参数传递,则始终生成链代码事件。
以下列表显示了必须传递两个令牌的常用方法。此列表适用于扩展的令牌分类框架标准。
  • addConversionRate(from_token_id: string, to_token_id: string, token_conversion_rate: number)
  • updateConversionRate(from_token_id: string, to_token_id: string, token_conversion_rate: number)
  • tokenConversion(from_token_id: string, to_token_id: string, to_org_id: string, to_user_id: string,token_quantity: number)
  • exchangeToken(fromTokenId: string, fromOrgId: string, fromUserId: string, fromTokenQuantity: number, toTokenId: string, toOrgId: string,toUserId: string,toTokenQuantity: number)
以下列表显示了不将令牌作为参数的常见方法以下列表适用于扩展令牌分类框架标准。
  • addTokenAdmin(org_id: string, user_id: string)
  • removeTokenAdmin(org_id: string, user_id: string)
  • addOrgAdmin(org_id: string, user_id: string)
  • removeOrgAdmin(org_id: string, user_id: string)
  • createAccount(org_id: string, user_id: string, token_type: string)
  • deleteHistoricalTransactions(time_to_expiration: Date)
  • initializeExchangePoolUser(org_id: string, user_id: string)
此列表显示了不将令牌作为扩展 ERC-1155 标准参数的常用方法。
  • addTokenAdmin(orgId: string, userId: string)
  • removeTokenAdmin(orgId: string, userId: string)
  • createAccount(orgId: string, userId: string, ftAccount: boolean, nftAccount: boolean)
  • createUserAccount(orgId: string, userId: string)
  • createTokenAccount(orgId: string, userId: string, tokenType: TokenType)
  • addTokenSysRole(orgId: string, userId: string, role: string)
  • removeTokenSysRole(orgId: string, userId: string, role: string)
  • transferTokenSysRole(fromOrgId: string, fromUserId: string, toOrgId: string, toUserId: string, role: string)
  • deleteHistoricalTransactions(time_to_expiration: Date)

TypeScript Chaincode 事件的 SDK 方法

createEvent
此方法基于指定的事件名称和有效负载生成事件。
public async createEvent(eventName: any, eventPayload: any, assets?: any)
参数:
  • eventName: string- 生成事件时要使用的事件名称。
  • eventPayload: map[string]interface{}- 生成事件时要使用的事件有效负载。
  • assets-(可选)标记资产可以作为参数传递到方法。
createEventForBatch
此方法为批处理操作(例如 mintBatchburnBatch 方法)生成事件。
public async createEventForBatch(eventName: any, eventPayload: any, quantities: number[], assets: any)
参数:
  • eventName: string- 生成事件时要使用的事件名称。
  • eventPayload: map[string]interface{}- 生成事件时要使用的事件有效负载。
  • quantities: number[]- 对应于每个令牌 ID 的金额列表,表示要在批处理方法事务处理中使用的令牌数。
  • assets-(可选)标记资产可以作为参数传递到方法。

转到 Chaincode 事件的 SDK 方法

CreateEvent
此方法基于指定的事件名称和有效负载生成事件。
func (m *Model) CreateEvent(eventName string, eventPayload map[string]interface{}, assets ...interface{})
参数:
  • eventName: string- 生成事件时要使用的事件名称。
  • eventPayload: map[string]interface{}- 生成事件时要使用的事件有效负载。
  • assets-(可选)标记资产可以作为参数传递到方法。
CreateEventForBatch
此方法为批处理操作(例如 mintBatchburnBatch 方法)生成事件。
func (m *Model) CreateEventForBatch(eventName string, eventPayload map[string]interface{}, quantities []float64, assets []interface{})
参数:
  • eventName: string- 生成事件时要使用的事件名称。
  • eventPayload: map[string]interface{}- 生成事件时要使用的事件有效负载。
  • quantities: []float64- 对应于每个令牌 ID 的金额列表,表示要在批处理方法事务处理中使用的令牌数。
  • assets-(可选)标记资产可以作为参数传递到方法。