鏈碼事件

區塊鏈 App 產生器的增強版本可以產生權杖作業的鏈碼事件。

鏈碼事件是交易執行時所發出的特定通知。事件包括可用於通知外部系統特定條件或區塊鏈分類帳狀態變更的交易資訊。您可以使用鏈碼事件與不屬於區塊鏈的應用程式進行即時整合和互動,並促進整個區塊鏈環境的事件導向工作流程和監控。鏈碼事件有兩個元件:事件名稱和有效負載。

所有 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...)
}

Chaincode 事件使用下列名稱和有效負載元件預設值。您可以視需要修改預設值。

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 鏈碼事件的 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 – 選擇性地將記號資產當作參數傳送至方法。