链代码事件

区块链应用程序构建器的增强版本可以为令牌操作生成链代码事件。

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

所有区块链应用程序构建器规范文件都支持链代码事件。如果启用链代码事件,则支架式项目中的所有控制器函数将发出事件,但 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 参数的标记。
{
    "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 链代码事件的 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 —(可选)可以将令牌资产作为参数传递到方法。

针对链代码事件执行 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 —(可选)可以将令牌资产作为参数传递到方法。

在区块链应用程序构建器链代码中生成事件

如果规范文件中的 events 参数设置为 true,则将为除指定为 getter API 的控制器 API 之外的所有控制器 API 生成链代码事件代码。以下示例显示了为 TypeScript 和 Go 启用链代码事件的控制器 API。
@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:控制器函数的名称。
  • Payload:包含控制器函数的所有输入参数的 JSON 对象。