弃用说明

本文档已弃用,并将在未来版本中移除。 controller 子模块的 keeper 暴露了两个遗留函数,分别允许自定义认证模块注册跨链账户,以及向该跨链账户发送数据包。

RegisterInterchainAccount

认证模块可以通过调用 RegisterInterchainAccount 开始注册跨链账户:
if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version, channeltypes.UNORDERED); err != nil {
    return err
}

return nil
version 参数用于支持 ICS-29 fee middleware,以便为 ICS-27 数据包提供中继者激励。ordering 参数允许指定所创建通道的排序方式;如果传入 NONE,则默认排序方式为 UNORDERED。RegisterInterchainAccount 的使用方应自行构造合适的 JSON 编码版本字符串并按需传入。如果在 version 参数中传入空字符串,则版本会在 controller handler 的 OnChanOpenInit 回调中初始化为默认值,从而使通道握手能够继续进行。 下面的代码片段展示了如何构造合适的跨链账户 Metadata,并将其编码为 JSON 字节串:
icaMetadata := icatypes.Metadata{
    Version:                icatypes.Version,
    ControllerConnectionId: controllerConnectionID,
    HostConnectionId:       hostConnectionID,
    Encoding:               icatypes.EncodingProtobuf,
    TxType:                 icatypes.TxTypeSDKMultiMsg,
}

appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata)
    if err != nil {
    return err
}
    if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion), channeltypes.UNORDERED); err != nil {
    return err
}
同样地,如果应用栈被配置为通过 ICS-29 fee middleware 路由,并且希望创建一个启用手续费的通道,则需要构造合适的 ICS-29 Metadata 类型:
icaMetadata := icatypes.Metadata{
    Version:                icatypes.Version,
    ControllerConnectionId: controllerConnectionID,
    HostConnectionId:       hostConnectionID,
    Encoding:               icatypes.EncodingProtobuf,
    TxType:                 icatypes.TxTypeSDKMultiMsg,
}

appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata)
    if err != nil {
    return err
}
    feeMetadata := feetypes.Metadata{
    AppVersion: string(appVersion),
    FeeVersion: feetypes.Version,
}

feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata)
    if err != nil {
    return err
}
    if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion), channeltypes.UNORDERED); err != nil {
    return err
}

SendTx

认证模块可以通过调用 SendTx 尝试发送一个数据包:
/ Authenticate owner
/ perform custom logic
    
/ Construct controller portID based on interchain account owner address
portID, err := icatypes.NewControllerPortID(owner.String())
    if err != nil {
    return err
}
    
/ Obtain data to be sent to the host chain. 
/ In this example, the owner of the interchain account would like to send a bank MsgSend to the host chain. 
/ The appropriate serialization function should be called. The host chain must be able to deserialize the transaction. 
/ If the host chain is using the ibc-go host module, `SerializeCosmosTx` should be used. 
    msg := &banktypes.MsgSend{
    FromAddress: fromAddr,
    ToAddress: toAddr,
    Amount: amt
}

data, err := icatypes.SerializeCosmosTx(keeper.cdc, []proto.Message{
    msg
})
    if err != nil {
    return err
}

/ Construct packet data
    packetData := icatypes.InterchainAccountPacketData{
    Type: icatypes.EXECUTE_TX,
    Data: data,
}

/ Obtain timeout timestamp
/ An appropriate timeout timestamp must be determined based on the usage of the interchain account.
/ If the packet times out, the channel will be closed requiring a new channel to be created.
    timeoutTimestamp := obtainTimeoutTimestamp()

/ Send the interchain accounts packet, returning the packet sequence
seq, err = keeper.icaControllerKeeper.SendTx(ctx, portID, packetData, timeoutTimestamp)
InterchainAccountPacketData 中的数据必须使用宿主链支持的格式进行序列化。 如果宿主链使用的是 ibc-go host chain 子模块,则应使用 SerializeCosmosTx。如果 InterchainAccountPacketData.Data 使用了宿主链不支持的格式进行序列化,则该数据包将无法被成功接收。

Deprecation Notice

This document is deprecated and will be removed in future releases. The controller submodule keeper exposes two legacy functions that allow respectively for custom authentication modules to register interchain accounts and send packets to the interchain account.

RegisterInterchainAccount

The authentication module can begin registering interchain accounts by calling RegisterInterchainAccount:
if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version, channeltypes.UNORDERED); err != nil {
    return err
}

return nil
The version argument is used to support ICS-29 fee middleware for relayer incentivization of ICS-27 packets. The ordering argument allows to specify the ordering of the channel that is created; if NONE is passed, then the default ordering will be UNORDERED. Consumers of the RegisterInterchainAccount are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the version argument, then the version will be initialized to a default value in the OnChanOpenInit callback of the controller’s handler, so that channel handshake can proceed. The following code snippet illustrates how to construct an appropriate interchain accounts Metadata and encode it as a JSON bytestring:
icaMetadata := icatypes.Metadata{
    Version:                icatypes.Version,
    ControllerConnectionId: controllerConnectionID,
    HostConnectionId:       hostConnectionID,
    Encoding:               icatypes.EncodingProtobuf,
    TxType:                 icatypes.TxTypeSDKMultiMsg,
}

appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata)
    if err != nil {
    return err
}
    if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion), channeltypes.UNORDERED); err != nil {
    return err
}
Similarly, if the application stack is configured to route through ICS-29 fee middleware and a fee enabled channel is desired, construct the appropriate ICS-29 Metadata type:
icaMetadata := icatypes.Metadata{
    Version:                icatypes.Version,
    ControllerConnectionId: controllerConnectionID,
    HostConnectionId:       hostConnectionID,
    Encoding:               icatypes.EncodingProtobuf,
    TxType:                 icatypes.TxTypeSDKMultiMsg,
}

appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata)
    if err != nil {
    return err
}
    feeMetadata := feetypes.Metadata{
    AppVersion: string(appVersion),
    FeeVersion: feetypes.Version,
}

feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata)
    if err != nil {
    return err
}
    if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion), channeltypes.UNORDERED); err != nil {
    return err
}

SendTx

The authentication module can attempt to send a packet by calling SendTx:
/ Authenticate owner
/ perform custom logic
    
/ Construct controller portID based on interchain account owner address
portID, err := icatypes.NewControllerPortID(owner.String())
    if err != nil {
    return err
}
    
/ Obtain data to be sent to the host chain. 
/ In this example, the owner of the interchain account would like to send a bank MsgSend to the host chain. 
/ The appropriate serialization function should be called. The host chain must be able to deserialize the transaction. 
/ If the host chain is using the ibc-go host module, `SerializeCosmosTx` should be used. 
    msg := &banktypes.MsgSend{
    FromAddress: fromAddr,
    ToAddress: toAddr,
    Amount: amt
}

data, err := icatypes.SerializeCosmosTx(keeper.cdc, []proto.Message{
    msg
})
    if err != nil {
    return err
}

/ Construct packet data
    packetData := icatypes.InterchainAccountPacketData{
    Type: icatypes.EXECUTE_TX,
    Data: data,
}

/ Obtain timeout timestamp
/ An appropriate timeout timestamp must be determined based on the usage of the interchain account.
/ If the packet times out, the channel will be closed requiring a new channel to be created.
    timeoutTimestamp := obtainTimeoutTimestamp()

/ Send the interchain accounts packet, returning the packet sequence
seq, err = keeper.icaControllerKeeper.SendTx(ctx, portID, packetData, timeoutTimestamp)
The data within an InterchainAccountPacketData must be serialized using a format supported by the host chain. If the host chain is using the ibc-go host chain submodule, SerializeCosmosTx should be used. If the InterchainAccountPacketData.Data is serialized using a format not supported by the host chain, the packet will not be successfully received.