ERC-721 NFT 锁定的执行方法

区块链应用程序构建器自动生成可用于锁定使用扩展 ERC-721 标准的不可替代令牌的方法。

锁定的令牌无法刻录或传输到其他用户。保留所有其他属性,例如令牌的状态、所有者和历史记录。在将令牌传输到另一个区块链网络(例如以太坊或多边形)时,您可以使用 NFT 锁定功能。

必须先将 Vault 管理器角色分配给用户,然后才能锁定 NFT。Vault 管理器是一种特殊类型的角色,即 TokenSys 角色。TokenSys 角色与基于资产的角色(例如刻录机、矿工和公证人)不同,与管理角色(例如 Token AdminOrg Admin)不同。当前,Blockchain App Builder 支持 vault TokenSys 角色。链代码具有 vault 角色的单个用户是链代码的 Vault 管理器,可以管理锁定的 NFT。

使用 NFT 锁定功能的典型流遵循以下步骤。
  • 创建具有可锁定行为的不可替换令牌。
  • 使用 AddTokenSysRole 方法将 vault 角色授予用户 Vault 管理器。
  • 调用 LockNFT 方法来锁定由令牌 ID 指定的不可替换令牌。

TokenSys 角色管理方法

AddTokenSysRole
此方法向指定用户添加 TokenSys 角色。此方法只能由链代码的 Token Admin 调用。
func (t *Controller) AddTokenSysRole(role string, orgId string, userId string) (interface{}, error) {
    accountId, err := t.Ctx.ERC721Account.GenerateAccountId(orgId, userId)
    if err != nil {
        return nil, err
    }
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.AddTokenSysRole", "TOKEN", map[string]string{"accountId": accountId})
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
    }
    return t.Ctx.ERC721Token.AddTokenSysRoleMember(role, accountId)
}
参数:
  • role: string- 要提供给用户的 TokenSys 角色的名称。
  • orgId: string - 当前组织中用户的成员服务提供者 (MSP) ID。
  • userId: string - 用户的用户名或电子邮件 ID。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
    "msg": "Successfully added role 'vault' to Account Id: oaccount~bf07f584a94be44781e49d9101bfaf58c6fbbe77a4dfebdb83c874c2caf03eba (Org-Id: Org1MSP, User-Id: user1)"
}
IsInTokenSysRole
此方法返回布尔值以指示用户是否具有指定的 TokenSys 角色。此方法只能由链代码的 Token Admin 调用。
func (t *Controller) IsInTokenSysRole(orgId string, userId string, role string) (interface{}, error) {
    accountId, err := t.Ctx.ERC721Account.GenerateAccountId(orgId, userId)
    if err != nil {
        return nil, err
    }
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.IsInTokenSysRole", "TOKEN")
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
    }
    return t.Ctx.ERC721Token.IsInTokenSysRoleMember(role, accountId)
}
参数:
  • role: string - 要检查的 TokenSys 角色的名称。
  • orgId: string - 当前组织中用户的成员服务提供者 (MSP) ID。
  • userId: string - 用户的用户名或电子邮件 ID。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
    "result": true,
    "msg": "Account Id oaccount~bf07f584a94be44781e49d9101bfaf58c6fbbe77a4dfebdb83c874c2caf03eba (Org-Id: Org1MSP, User-Id: user1) has vault role"
}
RemoveTokenSysRole
此方法将从指定用户中删除 TokenSys 角色。此方法只能由链代码的 Token Admin 调用。
func (t *Controller) RemoveTokenSysRole(role string, orgId string, userId string) (interface{}, error) {
    accountId, err := t.Ctx.ERC721Account.GenerateAccountId(orgId, userId)
    if err != nil {
        return nil, err
    }
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.RemoveTokenSysRole", "TOKEN", map[string]string{"accountId": accountId})
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
    }
    return t.Ctx.ERC721Token.RemoveTokenSysRoleMember(role, accountId)
}
参数:
  • role: string - 要删除的 TokenSys 角色的名称。
  • orgId: string - 当前组织中用户的成员服务提供者 (MSP) ID。
  • userId: string - 用户的用户名或电子邮件 ID。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
    "msg": "Successfully removed role 'vault' from Account Id: oaccount~bf07f584a94be44781e49d9101bfaf58c6fbbe77a4dfebdb83c874c2caf03eba (Org-Id: Org1MSP, User-Id: user1)"
}
TransferTokenSysRole
此方法将 TokenSys 角色从用户转移到其他用户。此方法只能由链代码的 Token Admin 调用。
func (t *Controller) TransferTokenSysRole(role string, fromOrgId string, fromUserId string, toOrgId string, toUserId string) (interface{}, error) {
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.TransferTokenSysRole", "TOKEN")
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller %s", err.Error())
    }
    fromAccountId, err := t.Ctx.ERC721Account.GenerateAccountId(fromOrgId, fromUserId)
    if err != nil {
        return nil, fmt.Errorf("error in TransferTokenSysRole. Error: %s", err)
    }
    toAccountId, err := t.Ctx.ERC721Account.GenerateAccountId(toOrgId, toUserId)
    if err != nil {
        return nil, fmt.Errorf("error in TransferTokenSysRole. Error: %s", err)
    }
    return t.Ctx.ERC721Token.TransferTokenSysRole(role, fromAccountId, toAccountId)
}
参数:
  • role: string - 要传输的 TokenSys 角色的名称。
  • fromOrgId: string- 要从其转移 TokenSys 角色的用户的成员资格服务提供商 (MSP) ID。
  • fromUserId: string - 要从其转移 TokenSys 角色的用户的用户名或电子邮件 ID。
  • toOrgId: string - 要将 TokenSys 角色转移到的用户的成员资格服务提供商 (MSP) ID。
  • toUserId: string - 要将 TokenSys 角色转移到的用户的用户名或电子邮件 ID。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
    "msg": "Successfully transfered role 'vault' from Account Id: ouaccount~f4e311528f03fffa7810753d643f66289ff6c9080fcf839902f28a1d3aff1789 (Org-Id: Org1MSP, User-Id: user1) to Account Id: ouaccount~ae5be2ae8f98d6d32f5d02b43877d987114e7937c7bacbc30390dcce09996a19 (Org-Id: Org1MSP, User-Id: user2)"
}
GetAccountsByTokenSysRole
此方法返回指定 TokenSys 角色的所有帐户 ID 的列表。此方法只能由链代码的 Token Admin 调用。
func (t *Controller) GetAccountsByTokenSysRole(role string) (interface{}, error) {
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.GetAccountsByTokenSysRole", "TOKEN")
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
    }
    return t.Ctx.ERC721Token.GetAccountsByTokenSysRole(role)
}
参数:
  • role: string - TokenSys 角色的名称。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
    "accountIds": [
        "oaccount~bf07f584a94be44781e49d9101bfaf58c6fbbe77a4dfebdb83c874c2caf03eba"
    ]
}
GetUsersByTokenSysRole
此方法返回具有指定 TokenSys 角色的所有用户的用户信息。此方法只能由链代码的 Token Admin 调用。
func (t *Controller) GetUsersByTokenSysRole(role string) (interface{}, error) {
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.GetUsersByTokenSysRole", "TOKEN")
    if err != nil && !auth {
        return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
    }
    return t.Ctx.ERC721Token.GetUsersByTokenSysRole(role)
}
参数:
  • role: string - TokenSys 角色的名称。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
   "Users":[
      {
         "accountId":"oaccount~bf07f584a94be44781e49d9101bfaf58c6fbbe77a4dfebdb83c874c2caf03eba",
         "orgId":"Org1MSP",
         "userId":"user1"
      }
   ]
}

NFT 锁定方法

LockNFT
此方法锁定指定的不可替换令牌。要锁定令牌,必须具有 TokenSys vault 角色的用户充当 Vault 管理器。此方法只能由令牌的所有者调用。
func (t *Controller) LockNFT(tokenId string) (interface{}, error) {
    return t.Ctx.ERC721Token.LockNFT(tokenId)
}
参数:
  • tokenID: string - 要锁定的令牌的 ID。
返回:
  • 成功时,标记对象的 JSON 表示形式。
返回值示例:
{
   "AssetType":"otoken",
   "Behavior":[
      "indivisible",
      "singleton",
      "mintable",
      "transferable",
      "lockable",
      "burnable",
      "roles"
   ],
   "CreatedBy":"oaccount~208e3345ac84b4849f0d2648b2f2f018019886a1230f99304ebff1b6a7733463",
   "CreationDate":"2023-10-20T12:39:50Z",
   "IsBurned":false,
   "IsLocked":true,
   "Mintable":{
      "Max_mint_quantity":20000
   },
   "On_sale_flag":false,
   "Owner":"oaccount~208e3345ac84b4849f0d2648b2f2f018019886a1230f99304ebff1b6a7733463",
   "Price":120,
   "Roles":{
      "minter_role_name":"minter"
   },
   "Symbol":"ART",
   "TokenDesc":"",
   "TokenId":"token1",
   "TokenMetadata":{
      "Description":"",
      "Image":"",
      "Painter_name":"",
      "Painting_name":""
   },
   "TokenName":"artcollection",
   "TokenStandard":"erc721+",
   "TokenType":"nonfungible",
   "TokenUnit":"whole",
   "TokenUri":"token1.example.com"
}
IsNFTLocked
此方法返回布尔值以指示指定的标记是否已锁定。此方法只能由令牌所有者、 Vault 管理器(具有 TokenSys vault 角色的用户)或链代码的 Token Admin 调用。
func (t *Controller) IsNFTLocked(tokenId string) (interface{}, error) {
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.IsNFTLocked", "TOKEN", map[string]string{"tokenId": tokenId})
    if err != nil && !auth {
        isCallerTokenSysRoleHolder, error := t.Ctx.ERC721Token.IsCallerTokenSysRoleHolder(constants.Vault)
        if error != nil {
            return nil, error
        }
        if !isCallerTokenSysRoleHolder {
            return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
        }
    }
    return t.Ctx.ERC721Token.IsNFTLocked(tokenId)
}
参数:
  • tokenID: string - 标记的 ID。
返回:
  • 成功后,将显示包含操作相关详细信息的消息。
返回值示例:
{
   "isNFTLocked":true
}
GetAllLockedNFTs
此方法返回所有锁定的不可替代标记的列表。此方法只能由 Vault 管理器(具有 TokenSys vault 角色的用户)或链代码的 Token Admin 调用。
func (t *Controller) GetAllLockedNFTs() (interface{}, error) {
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.GetAllLockedNFTs", "TOKEN")
    if err != nil && !auth {
        isCallerTokenSysRoleHolder, error := t.Ctx.ERC721Token.IsCallerTokenSysRoleHolder(constants.Vault)
        if error != nil {
            return nil, error
        }
        if !isCallerTokenSysRoleHolder {
            return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
        }
    }
    return t.Ctx.ERC721Token.GetAllLockedNFTs()
}
参数:
返回:
  • 成功时,锁定不可替代的令牌对象的数组。
返回值示例:
[
   {
      "key":"token1",
      "valueJson":{
         "AssetType":"otoken",
         "Behavior":[
            "indivisible",
            "singleton",
            "mintable",
            "transferable",
            "lockable",
            "burnable",
            "roles"
         ],
         "CreatedBy":"oaccount~208e3345ac84b4849f0d2648b2f2f018019886a1230f99304ebff1b6a7733463",
         "CreationDate":"2023-10-20T12:39:50Z",
         "IsBurned":false,
         "IsLocked":true,
         "Mintable":{
            "Max_mint_quantity":20000
         },
         "On_sale_flag":false,
         "Owner":"oaccount~208e3345ac84b4849f0d2648b2f2f018019886a1230f99304ebff1b6a7733463",
         "Price":120,
         "Roles":{
            "minter_role_name":"minter"
         },
         "Symbol":"ART",
         "TokenDesc":"",
         "TokenId":"token1",
         "TokenMetadata":{
            "Description":"",
            "Image":"",
            "Painter_name":"",
            "Painting_name":""
         },
         "TokenName":"artcollection",
         "TokenStandard":"erc721+",
         "TokenType":"nonfungible",
         "TokenUnit":"whole",
         "TokenUri":"token1.example.com"
      }
   }
]
GetAllLockedNFTsByOrg
此方法返回指定组织和(可选)指定用户的所有锁定的不可替代标记的列表。此方法只能由 Vault 管理器(具有 TokenSys vault 角色的用户)或链代码的 Token Admin 调用。
func (t *Controller) GetLockedNFTsByOrg(orgId string, userId ...string) (interface{}, error) {
    auth, err := t.Ctx.ERC721Auth.CheckAuthorization("ERC721TOKEN.GetLockedNFTsByOrg", "TOKEN")
    if err != nil && !auth {
        isCallerTokenSysRoleHolder, error := t.Ctx.ERC721Token.IsCallerTokenSysRoleHolder(constants.Vault)
        if error != nil {
            return nil, error
        }
        if !isCallerTokenSysRoleHolder {
            return nil, fmt.Errorf("error in authorizing the caller  %s", err.Error())
        }
    }
    return t.Ctx.ERC721Token.GetLockedNFTsByOrg(orgId, userId...)
}
参数:
  • orgId: string - 当前组织中用户的成员服务提供者 (MSP) ID。
  • userId: string - 用户的用户名或电子邮件 ID(可选)。
返回:
  • 成功时,锁定不可替代的令牌对象的数组。
返回值示例:
[
   {
      "key":"token1",
      "valueJson":{
         "AssetType":"otoken",
         "Behavior":[
            "indivisible",
            "singleton",
            "mintable",
            "transferable",
            "lockable",
            "burnable",
            "roles"
         ],
         "CreatedBy":"oaccount~208e3345ac84b4849f0d2648b2f2f018019886a1230f99304ebff1b6a7733463",
         "CreationDate":"2023-10-20T12:39:50Z",
         "IsBurned":false,
         "IsLocked":true,
         "Mintable":{
            "Max_mint_quantity":20000
         },
         "On_sale_flag":false,
         "Owner":"oaccount~208e3345ac84b4849f0d2648b2f2f018019886a1230f99304ebff1b6a7733463",
         "Price":120,
         "Roles":{
            "minter_role_name":"minter"
         },
         "Symbol":"ART",
         "TokenDesc":"",
         "TokenId":"token1",
         "TokenMetadata":{
            "Description":"",
            "Image":"",
            "Painter_name":"",
            "Painting_name":""
         },
         "TokenName":"artcollection",
         "TokenStandard":"erc721+",
         "TokenType":"nonfungible",
         "TokenUnit":"whole",
         "TokenUri":"token1.example.com"
      }
   }
]