• BEPs协议:BUMO STO 10 协议


    BUMO STO 10 协议

    简介

    STO 10 (Security Token Standard)是指基于 BUMO 智能合约发行证券型 token 的标准协议。该标准在 CTP 10 的基础上制定了增发 token,销毁 token,存储相关法律文件,将 token进行分片 ( tranche ),为 tranche 设置锁定期等约束条件,允许将指定 tranche 的 token 授权给第三方操作人,添加控制者 ( 如监控部门 ) 的相关功能。

    目标

    基于该协议标准发行的 token,能够在任何司法管辖区内发行和管理,并能够符合相关的监管限制。

    规则

    BUMO 智能合约由 JavaScript 语言实现, 包含初始化函数 init 和两个入口函数 main、query 。init 函数用于合约创建时初始化,main 函数主要负责数据写入,query 函数负责数据查询。

    STO 属性

    Token 基本信息

    key: global_attribute
    value: {
        "version": "1.0",
        "name": "Security Token",
        "symbol": "STO",
        "decimals": 8,
        "totalSupply": "100000",
        "scheduledTotalSupply":"100000",
        "owner":""
    }
    
    • version: 版本
    • name: Token 名称
    • symbol: Token 符号
    • decimals: Token 精度
    • totalSupply: Token 已发行总量,其值等于 10^decimals已发行量。假如,当前已发行总量是 10000, 精度为 8的 token,totalSupply = 10 ^ 8 * 10000, 结果是 1000000000000。*
    • scheduledTotalSupply: Token 计划发行的总量, 0 表示不限制发行量, 大于 0 表示限制发行总量。其值等于10^decimals计划发行量。假如,计划要发行总量是 10000, 精度为 8 的 Token,scheduledTotalSuppl = 10 ^ 8 * 10000, 结果是 1000000000000。*
    • owner: Token 所有权拥有者

    Tranche 属性及限制

    key: tranche_attribute_id
    value: {
        "description": "private",
        "limits": [{
            "name": "lockupPeriod",
            "value": "1517470155872949",
        },
        ……
        ]
    }
    
    • id: tranche 的 id
    • description: tranche 的描述信息
    • limits: 约束
    • name: 约束名称
    • value: 约束内容

    所有 tranche 余额总和

    key: balance_tokenHolder
    value: {
        "value": "100000000", 
        "tranches": ["0", "1",……]
    }
    
    • tokenHolder: Token 持有人
    • value: 余额总数
    • tranches: trancheId 列表

    Tranche 余额

    key: tranche_tokenHolder_id
    value: "10000"
    
    • tokenHolder: Token 持有人
    • id: trancheId
    • value: tranche 余额总量

    操作者

    key: operator_tokenHolder_operatorAddress
    value: ["0", "1", ……]
    
    • tokenHolder: Token 持有人
    • operatorAddress: 操作者地址
    • tranches: trancheId 列表, 空列表表示授权所有分片,非空列表表示授权到指定的分片

    控制者

    key: global_controller
    value: [address1, addres2, ...]
    
    • controllers: 控制者列表
    • address: 控制者地址

    授权

    key: allowance_tokenHolder_tranche_spenderAddress
    value: "1000"
    
    • tokenHolder: Token 持有人
    • tranche: 指定 trancheId
    • spenderAddress: 被授权的账户地址
    • value: 授权数量

    文档

    key: document_documentName
    value: {
        "url": "https://BUMO.io/BUMO-Technology-White-Paper-cn",
        "hashType": "sha256",
        "documentHash": "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3",
        "provider": "buQXRbzyDaVpX3JT3Wd2gj2U2ZzVWZRpwcng",
        "date": 1544595438978280
    }
    
    
    • documentName: 文档名称
    • url: 文档链接地址
    • hashType: 哈希类型
    • documentHash: 哈希的 16 进制字符串
    • provider: 文档提供者
    • data: 提供日期

    事件

    函数setDocumentcreateTranchetransferWithDatatransferFromWithDatatransferFromToTranchetransferTranchetransferToTranchetransfersToTranchecontrollerTransfercontrollerRedeemauthorizeOperatorrevokeOperatorauthorizeOperatorForTrancherevokeOperatorForTrancheoperatorTransferTrancheoperatorRedeemTrancheissueissueToTrancheredeemredeemFromredeemTrancheredeemFromTranchetransferapproveapproveTranchetransferFrom会触发事件,事件是调用tlog接口,在区块链上记录一条交易日志,该日志记录了函数调用详情,方便用户阅读。

    tlog定义如下:

    tlog(topic,args...);
    
    
    • tlog会产生一笔交易写在区块上
    • topic: 日志主题,必须为字符串类型,参数长度(0,128]
    • args...: 最多可以包含5个参数,参数类型可以是字符串、数值或者布尔类型,每个参数长度(0,1024]

    功能函数

    BUMO ATP 20 协议中的函数包括tokenInfosetDocumentgetDocumentcreateTranchebalanceOfbalanceOfTranchetranchesOftransferWithDatatransferFromToTranchetransferTranchetransferToTranchetransfersToTrancheisControllablecontrollerTransfercontrollerRedeemauthorizeOperatorrevokeOperatorauthorizeOperatorForTrancherevokeOperatorForTrancheisOperatorisOperatorForTrancheoperatorTransferTrancheoperatorRedeemTrancheisIssuableissueissueToTrancheredeemredeemFromredeemTrancheredeemFromTranchecanTransfercanTransferTranchecanTransferToTranchetransfertransferFromapproveapproveTrancheallowanceallowanceForTranche

    tokenInfo

    • 功能

      查询 token 详情。

    • 入口函数

      query

    • 参数

      {
          "method": "tokenInfo
      }
      
    • 返回值

      {
          "result":{
              "type": "string",
              "value": {
                  "tokenInfo": {
                      "name": "DemoToken",
                      "symbol": "STP",
                      "decimals": 8,
                      "totalSupply": "10000000",
                      "scheduledTotalSupply": "10000000",
                      "owner": "buQXRbzyDaVpX3JT3Wd2gj2U2ZzVWZRpwcng",
                      "version": "1.0"
                  }
              }
          }
      } 
      

    setDocument

    注意:仅限于 token 的所有权拥有人和控制者使用。

    • 功能

      设置法律文件或其他参考资料

    • 入口函数

      main

    • 参数

      {
          "method":"setDocument",
          "params":{
              "name": "BUMO-Technology-White-Paper-cn",
              "url": "https://BUMO.io/BUMO-Technology-White-Paper-cn",
              "hashType": "sha256",
              "documentHash": "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3"
          }
      }
      - name: 文档名称,长度范围[1,256]
      - url: 文档在线链接地址,长度范围[10,128k]
      - hashType: 计算文档哈希的类型,长度范围[1,16]
      - documentHash: 文档哈希的16进制字符串
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('setDocument', sender, name, url, hashType, documentHash);
      

      topic: 方法名,这里是 'setDocument'

      sender: 合约调用账户地址

      name: 文档名称

      url: 文档在线链接地址

      hashType: 哈希类型

      documentHash: 哈希16进制字符串

    getDocument

    • 功能

      查询法律文件或其他参考资料

    • 入口函数

      query

    • 参数

      {
          "method":"getDocument",
          "params":{
              "name": "BUMO-Technology-White-Paper-cn"
          }
      }
      - name: 文档名称
      
    • 返回值

      {
          "result": {
              "type": "string",
              "value": {
                  "document": {
                      "url": "https://BUMO.io/BUMO-Technology-White-Paper-cn",
                      "hashType": "sha256",
                      "documentHash": "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3",
                      "provider": "buQXRbzyDaVpX3JT3Wd2gj2U2ZzVWZRpwcng",
                      "date": 1544595438978280
                  }
              }
          }
      }
      - url: 文档在线链接地址
      - hashType: 计算哈希的方式
      - documentHash: 哈希的 16 进制字符串
      - provider: 文档提供者
      - date: 上传日期
      

    createTranche

    注意:仅限于 token 的所有权拥有者使用。

    • 功能

      创建分支(只允许发行人操作)。

    • 入口函数

      main

    • 参数

      {
          "method":"createTranche",
          "params":{
              "tranche":{
                  "id": "1",
                  "description": "private",
                  "limits":[{
                      "name":"lockupPeriod",
                      "value":"1517470155872949"
                  }],
                  "tokenHolders":{
                      "buQoqGbz7o6RSkDympf8LrqSe8z4QkiBjcHw": "1000",
                      ...
                  }
              }
          }
      }
      - id: trancheid,大小范围[1,2^63-1]
      - description: tranche 描述,长度范围[1,64k]
      - limits: 约束条件
      - name: 约束名称,长度范围[1,64]
      - value: 约束内容,长度范围[1,256]
      - tokenHolders: 分发的账户列表,最多支持8个
      

    注意: 最多只允许分配给8个 tokenHolders

    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('createTranche', sender, id, description, limits, tokenHolders);
      

      topic: 方法名,这里是 'createTranche'

      sender: 合约调用账户地址

      id: trancheid

      description: tranche描述

      limits: 约束条件, json 字符串

      tokenHolders: 分发的账户列表, json 字符串

    balanceOf

    • 功能

      查询指定账户下的所有 tranche 的 token 总和。

    • 入口函数

      query

    • 参数

      {
          "method": "balanceOfTranche",
          "params":{
              "address": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      {
          "result": {
              "type": "string",
              "value": {
                  "balance": "0.01"
              }
          }
      }
      

    balanceOfTranche

    • 功能

      查询指定账户下的指定 tranche 的 token 余额

    • 入口函数

      query

    • 参数

      {
          "method":"balanceOfTranche",
          "params":{
              "tranche": "1",
              "address": "buQZW68otiwmNPgzcBceuQ7NzFLX46FVyh65"
          }
      }
      
    • 返回值

      {
          "result": {
              "type": "string",
              "value": {
                  "balance": "1000"
              }
          }
      }
      

    tranchesOf

    • 功能

      查询与特定 token 持有者地址关联的所有 tranche 数量

    • 入口函数

      query

    • 参数

      {
          "method":"tranchesOf",
          "params":{
              "address": "buQZW68otiwmNPgzcBceuQ7NzFLX46FVyh65"
          }
      }
      
    • 返回值

      {
          "result": {
              "type": "string",
              "value": {
                  "balance": "30000"
              }
          }
      }
      

    transferWithData

    • 功能

      将合约触发者的 token 转移给目标账户,并允许携带任意数据。

    • 入口函数

      main

    • 参数

      {
          "method": "transferWithData",
          "params":{
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100",
              "data": ""
          }
      }
      
      - to: Token 收入方地址
      - value: Token 数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,128k]
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('transferWithData', sender, to, value, data);
      

      topic: 方法名,这里是 'transferWithData'

      ​sender: 合约调用账户地址

      ​to: 目标账户地址

      value: 转移数量(字符串类型)

      ​data: 附加信息

    transferFromWithData

    • 功能

      将指定 token 持有人的 token 转移给目标账户(合约触发者必须被授予足够的份额),并允许携带任意数据。

    • 入口函数

      main

    • 参数

      {
          "method": "transferFromWithData",
          "params":{
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100",
              "data": ""
          }
      }
      - from: Token 支出方地址
      - to: Token 收入方地址
      - value: Token 数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,128k]
      
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

        tlog('transferFromWithData', sender, from, to, value, data);
      

      ​ topic: 方法名,这里是 'transferFromWithData'

      ​ sender: 合约调用账户地址

      ​ from: Token 支出方地址

      ​ to: 目标账户地址

      ​ value: 转移数量(字符串类型)

      ​ data: 附加信息

    transferFromToTranche

    • 功能

      将指定 token 持有人的指定 tranche 的 token 转移给目标账户,并允许携带任意数据。

    • 入口函数

      main

    • 参数

      {
          "method": "transferFromToTranche",
          "params":{
              "from": "buQm44k6VxqyLM8gQ7bJ49tJSjArhFsrVUKY",
              "fromTranche": "0",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "toTranche": "1",
              "value": "100",
              "data": ""
          }
      }
      - from: Token 支出方地址
      - fromTranche: Token 支出方 tranche 的 id,大小范围[0,2^63-1]
      - to: Token 收入方地址
      - toTranche: Token 收入方 tranche 的 id,大小范围[0,2^63-1]
      - value: Token 数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,128k]
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('transferFromToTranche', sender, from + '_' + fromTranche, to + '_' + toTranche, value, data);
      

      topic: 方法名,这里是 'transferFromToTranche'

      sender: 合约调用账户地址

      from: Token 支出方地址

      fromTranche: Token 支出方 tranche 的 id

      to: Token 收入方地址

      toTranche: Token 收入方 tranche 的 id

      value: Token 数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    transferTranche

    • 功能

      将合约触发者的指定 tranche 的 token 转移给目标账户的指定 tranche,并允许携带任意数据。

    • 入口函数

      main

    • 参数

      {
          "method": "transferTranche",
          "params":{
              "tranche": "0",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100",
              "data": ""
          }
      }
      - tranche: Token 支出方和收入方 tranche 的 id,大小范围[0,2^63-1]
      - to: Token 收入方地址
      - value: Token 数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,128k]
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('transferTranche', sender, tranche, to, value, data);
      

      topic: 方法名,这里是 'transferTranche'

      sender: 合约调用账户地址

      tranche: tranche的id

      to: Token 收入方地址

      value: Token 数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    transferToTranche

    • 功能

      将合约触发者的指定 tranche 的 token 转移给目标账户的指定 tranche,并允许携带任意数据。

    • 入口函数

      main

    • 参数

      {
          "method": "transferToTranche",
          "params":{
              "fromTranche": "0",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "toTranche": "1",
              "value": "100",
              "data": ""
          }
      }
      - fromTranche: Token 支出方 tranche 的 id,大小范围[0,2^63-1]
      - to: Token 收入方地址
      - toTranche: Token 收入方 tranche 的 id,大小范围[0,2^63-1]
      - value: Token 数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,128k]
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('transferToTranche', sender, fromTranche, to + '_' + toTranche, value, data);
      

      topic: 方法名,这里是 'transferToTranche'

      sender: 合约调用账户地址

      fromTranche: Token 支出方 tranche 的 id

      to: Token 收入方地址

      toTranche: Token 收入方 tranche 的 id

      value: Token 数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    transfersToTranche

    • 功能

      将合约触发者的指定的 tranche 的 token 转移给多个目标账户的某个 tranche,并允许携带任意数据。

    • 入口函数

      main

    • 参数

      {
          "method": "transfersToTranche",
          "params":{
              "fromTranche": "0",
              "toTranche": "1",
              "tokenHolders": {
                  Address1: value1,
                  Address2: value2,
                   …
              },
              "data": ""
          }
      }
      - fromTranche: Token 支出方 tranche 的 id,大小范围[0,2^63-1]
      - toTranche: Token 收入方 tranche 的 id,大小范围[0,2^63-1]
      - tokenHolders: Token 收入方列表
      - Address1/Address2/...: Token 收入方地址
      - value1/value2/...: Token 转出数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,128k]
      
    • 返回值

      成功:返回目标账户的 tranche

      失败:抛出异常

    • 事件

      tlog('transfersToTranche', sender, fromTranche, toTranche, tokenHolders, data);
      

      topic: 方法名,这里是 'transfersToTranche'

      sender: 合约调用账户地址

      fromTranche: Token 支出方 tranche 的 id

      tokenHolders: Token 收入方列表,json字符串

      toTranche: Token 收入方 tranche 的 id

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    isControllable

    注意:如果 isControllable 是 true,那么 controller 在不需要授权的情况下,可以使用 operatorTransferTranche 和 operatorRedeemTranche 。

    • 功能

      判断当前 token 是否是可控制的,是否可由司法/指定账户(不需要授权)控制两个账户之间的流通。

    • 入口函数

      query

    • 参数

      {
          "method": "isControllable"
      }
      
    • 返回值

      成功: true

      失败: false

    controllerTransfer

    注意:在某些法域中,发行人(或由发行人委托的实体)可能需要保留强制转移 token 的能力。这可能是为了解决法律纠纷或法院命令,或补救投资者失去访问他们的私钥。

    • 功能

      允许授权的地址在任何两个令牌持有者之间传递 token。

    • 入口函数

      main

    • 参数

      {
          "method": "controllerTransfer",
          "params":{
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "fromTranche": "1",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "toTranche": "2",
              "value": "100",
              "data": "",
              "operatorData": ""
          }
      }
      - from: Token 支出方地址
      - fromTranche: Token 支出方 tranche 的 id,大小范围[0,2^63-1]
      - to: Token 收入方地址
      - toTranche: Token 收入方 tranche 的 id,大小范围[0,2^63-1]
      - value: Token 数量,大小范围[0,2^63-1]
      - data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,64k]
      - operatorData: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。长度范围[0,64k]
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('controllerTransfer', sender, from + '_' + fromTranche, to + '_' + toTranche, value, data + "; " + operatorData);
      

      topic: 方法名,这里是 'controllerTransfer'

      sender: 合约调用账户地址

      from: Token 支出方地址

      fromTranche: Token 支出方 tranche 的 id

      to: Token 收入方地址

      toTranche: Token 收入方 tranche 的 id

      value: Token 数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

      operatorData: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    controllerRedeem

    注意:在某些法域中,发行人(或由发行人委托的实体)可能需要保留强制转移 token的能力。这可能是为了解决法律纠纷或法院命令,或补救投资者失去访问他们的私钥。

    • 功能

      允许授权的地址为任何Token持有者赎回 token。

    • 入口函数

      main

    • 参数

      {
          "method": "controllerRedeem",
          "params":{
              "tokenHolder": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "tranche": "1",
              "value": "100",
              "data": "",
              "operatorData": ""
          }
      }
      
      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是签名数据(例如,动态白名单),但是足够灵活以适应其他用例。
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('controllerRedeem', sender, tokenHolder, tranche, value, data);
      

      topic: 方法名,这里是 'controllerRedeem'

      sender: 合约调用账户地址

      tokenHolder: Token 持有人地址

      tranche: Tranche 的 id

      value: Token 数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    authorizeOperator

    • 功能

      对合约触发者的所有 tranche 授权一个操作者。

    • 入口函数

      main

    • 参数

      {
          "method": "authorizeOperator",
          "params":{
              "operator": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('authorizeOperator', sender, operator);
      

      topic: 方法名,这里是 'authorizeOperator'

      sender: 合约调用账户地址

      operator: 操作人

    revokeOperator

    • 功能

      撤消对之前合约触发者的所有 tranche 的操作者的授权。

    • 入口函数

      main

    • 参数

      {
          "method": "revokeOperator",
          "params":{
              "operator": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('revokeOperator', sender, operator);
      

      topic: 方法名,这里是 'revokeOperator'

      sender: 合约调用账户地址

      operator: 操作人

    authorizeOperatorForTranche

    • 功能

      对合约触发者的指定 tranche 授权一个操作者。

    • 入口函数

      main

    • 参数

      {
          "method": "authorizeOperatorForTranche",
          "params":{
              "tranche": "1",
              "operator": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('authorizeOperatorForTranche', sender, tranche, operator);
      

      topic: 方法名,这里是 'authorizeOperatorForTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      operator: 操作人

    revokeOperatorForTranche

    • 功能

      撤消对之前合约触发者的指定 tranche 的操作者的授权。

    • 入口函数

      main

    • 参数

      {
          "method": "revokeOperatorForTranche",
          "params":{
              "tranche": "1",
              "operator": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('revokeOperatorForTranche', sender, tranche, operator);
      

      topic: 方法名,这里是 'revokeOperatorForTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      operator: 操作人

    isOperator

    • 功能

      判断是否是 token 持有人的所有 tranche 的操作人。

    • 入口函数

      query

    • 参数

      {
          "method": "isOperator",
          "params":{
              "operator": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV"
          }
      }
      
    • 返回值

      成功: true

      失败: false

    isOperatorForTranche

    • 功能

      判断是否是 token 持有人的指定 tranche 的操作人。

    • 入口函数

      query

    • 参数

      {
          "method": "isOperatorForTranche",
          "params":{
              "tranche": "1",
              "operator": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV"
          }
      }
      
    • 返回值

      成功: true

      失败: false

    operatorTransferTranche

    • 功能

      允许操作员代表 token 持有者在指定分段内转移 token。

    • 入口函数

      main

    • 参数

      {
          "method": "operatorTransferTranche",
          "params":{
              "tranche": "1",
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100",
              "data": "",
              "operatorData": ""
          }
      }
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('operatorTransferTranche', sender, tranche, from, to, value, data + '; ' + operatorData);
      

      topic: 方法名,这里是 'operatorTransferTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      from: Token 支出方地址

      to: Token 收入方地址

      value: Token 数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

      operatorData: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    operatorRedeemTranche

    • 功能

      允许操作员代表 token 持有者在指定分段内赎回 token(token 总量会减少)。

    • 入口函数

      main

    • 参数

      {
          "method": "operatorRedeemTranche",
          "params":{
              "tranche": "1",
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100",
              "operatorData": ""
          }
      }
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('operatorRedeemTranche', sender, tranche, tokenHolder, value, operatorData);
      

      topic: 方法名,这里是 'operatorRedeemTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      tokenHolder: Token 持有人

      value: Token 数量

      operatorData: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    isIssuable

    • 功能

      证券 token 发行者可以指定发行完成了 token(即没有新的 token 可以被铸造或发行)。

    • 入口函数

      query

    • 参数

      {
          "method": "isIssuable"
      }
      
    • 返回值

      成功: true

      失败: false

    issue

    • 功能

      增加指定 token 持有人的总供给量。

    • 入口函数

      main

    • 参数

      {
          "method": "issue",
          "params":{
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "nowSupply": "1000000000000",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('issue', sender, tokenHolder, nowSupply, data);
      

      topic: 方法名,这里是 'issue'

      sender: 合约调用账户地址

      tokenHolder: Token 持有人

      nowSupply: 当前的发行量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    issueToTranche

    • 功能

      增加指定 token 持有人的指定 tranche 的供给量。

    • 入口函数

      main

    • 参数

      {
          "method": "issueToTranche",
          "params":{
              "tranche": "",
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "nowSupply": "1000000000000",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('issueToTranche', sender, tranche, tokenHolder, nowSupply, data);
      

      topic: 方法名,这里是 'issueToTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      tokenHolder: Token 持有人

      nowSupply: 当前的发行量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    redeem

    • 功能

      从合约触发者赎回指定量的 token (总供给量会减少)。

    • 入口函数

      main

    • 参数

      {
          "method": "redeem",
          "params":{
              "value": "1000000000000",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('redeem', sender, value, data);
      

      topic: 方法名,这里是 'redeem'

      sender: 合约调用账户地址

      value: 赎回的数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    redeemFrom

    • 功能

      从指定的 token 持有人中赎回指定量的 token (总供给量会减少)。

    • 入口函数

      main

    • 参数

      {
          "method": "redeemFrom",
          "params":{
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "1000000000000",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('redeemFrom', sender, tokenHolder, value, data);
      

      topic: 方法名,这里是 'redeemFrom'

      sender: 合约调用账户地址

      tokenHolder: Token 持有人地址

      value: 赎回的数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    redeemTranche

    • 功能

      从合约触发者的指定的 tranche 赎回指定量的 token (总供给量会减少)。

    • 入口函数

      main

    • 参数

      {
          "method": "redeemTranche",
          "params":{
              "tranche": "1",
              "value": "1000000000000",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('redeemTranche', sender, tranche, value, data);
      

      topic: 方法名,这里是 'redeemTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      value: 赎回的数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    redeemFromTranche

    • 功能

      从指定的 token 持有人中赎回指定量的 token (总供给量会减少)(必须被授予足够的份额)。

    • 入口函数

      main

    • 参数

      {
          "method": "redeemFromTranche",
          "params":{
              "tranche": "1",
              "tokenHolder": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "1000000000000",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出异常

    • 事件

      tlog('redeemFrom', sender, tranche, tokenHolder, value, data);
      

      topic: 方法名,这里是 'redeemFrom'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      tokenHolder: Token 持有人地址

      value: 赎回的数量

      data: 允许随传输一起提交任意数据,以便进行解释或记录。这可以是授权传输的签名数据(例如,动态白名单),但是足够灵活以适应其他用例。

    canTransfer

    • 功能

      能否传输成功。

    • 入口函数

      query

    • 参数

      {
          "method": "canTransfer",
          "params":{
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出错误信息

    canTransferTranche

    • 功能

      指定 tranche 内的 token 能否被传输成功。

    • 入口函数

      query

    • 参数

      {
          "method": "canTransferByTranche",
          "params":{
              "tranche": "",
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              “value”: "100",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出错误信息

    canTransferToTranche

    • 功能

      指定 tranche 内的 token 转移给目标指定 tranche 内能否被传输成功。

    • 入口函数

      query

    • 参数

      {
          "method": "canTransferByTranche",
          "params":{
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "fromTranche": "1",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "toTranche": "2",
              “value”: "100",
              "data": ""
          }
      }
      
    • 返回值

      成功: true

      失败: 抛出错误信息

    transfer

    • 功能

      将合约触发者的 token 转移给目标账户。

    • 入口函数

      main

    • 参数

      {
          "method": "transfer",
          "params":{
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100"
          }
      }
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('transfer', sender, to, value);
      

      topic: 方法名,这里是'transfer'

      sender: 合约调用账户地址

      to: 目标账户地址

      value: 转移数量(字符串类型)

    transferFrom

    • 功能

      将指定 token 持有人的 token 转移给目标账户 (合约触发者必须被授予足够的份额)。

    • 入口函数

      main

    • 参数

      {
          "method": "transferFrom",
          "params":{
              "from": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "to": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "value": "100"
          }
      }
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('transferFrom', sender, from, to, value);
      

      topic: 方法名,这里是'transferFrom'

      sender: 合约调用账户地址

      from: 源账户地址

      to: 目标账户地址

      value: 转移数量(字符串类型)

    approve

    • 功能

      允许指定账户代表Token持有者操作 token。

    • 入口函数

      main

    • 参数

      {
          "method": "approve",
          "params":{
              "spender": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "value": "100"
          }
      }
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('approve', sender, spender, value);
      

      topic: 方法名,这里是'approve'

      sender: 合约调用账户地址

      spender: 被授权账户地址

      value: 被授权可转移数量(字符串类型)

    approveTranche

    • 功能

      允许指定账户代表 token持有者操作 token。

    • 入口函数

      main

    • 参数

      {
          "method": "approveTranche",
          "params":{
              "tranche": "1",
              "spender": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj",
              "value": "100"
          }
      }
      
    • 返回值

      成功:true

      失败:抛出异常

    • 事件

      tlog('approveTranche', sender, tranche, spender, value);
      

      topic: 方法名,这里是 'approveTranche'

      sender: 合约调用账户地址

      tranche: Tranche 的 id

      spender: 被授权账户地址

      value: 被授权可转移数量(字符串类型)

    allowance

    • 功能

      查询允许指定账户代表 token持有者操作 token数量。

    • 入口函数

      query

    • 参数

      {
          "method": "allowance",
          "params":{
              "owner": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "spender": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      {
          "result": {
              "type": "string",
              "value": {
                  "allowance": "10000000"
              }
          }
      }
      

    allowanceForTranche

    • 功能

      查询允许指定账户代表 token 持有者操作 token 数量。

    • 入口函数

      query

    • 参数

      {
          "method": "allowanceForTranche",
          "params":{
              "tranche": "1",
              "owner": "buQoP2eRymAcUm3uvWgQ8RnjtrSnXBXfAzsV",
              "spender": "buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"
          }
      }
      
    • 返回值

      {
          "result": {
              "type": "string",
              "value": {
                  "allowance": "100000"
              }
          }
      }
      

    合约入口

    init

    • 创建合约时候,触发合约 init 入口函数,负责合约创建时的初始化。

    • 函数

      function init(input_str){
      }
      
      
    • 参数Json结构

      {
          "params":{
              "name": "123",
              "symbol": "STP",
              "description": "STP",
              "decimals": 8,
              "nowSupply": "10000000",
              "scheduledTotalSupply": "10000000",
              "icon": "",
              "controllers": ["buQnTmK9iBFHyG2oLce7vcejPQ1g5xLVycsj"]
          }
      }
      - name: Token 名称,长度范围[1,64]
      - code: Token 符号,长度范围[1,64]
      - description: Token 描述,长度范围[1,64k]
      - decimals: Token 符号,即能支持的小数点位置,大小范围[0,8]
      - nowSupply: Token 当前发行量,大小范围[0,2^63-1],其值等于10^decimals*发行量。假如当前要发行一笔数量是 10000, 精度为8的 token,nowSupply = 10 ^ 8 * 10000, 结果是 1000000000000。
      - scheduledTotalSuppl: Token 计划发行总量,大小范围[0,2^63-1],0 表示不限量发行,大于 0 表示限量发行,其值等于10^decimals*计划发行量。假如计划要发行总量是 10000, 精度为 8 的 token,scheduledTotalSuppl = 10 ^ 8 * 10000, 结果是 1000000000000。
      - icon: base64位编码,图标文件大小是32k以内,推荐200*200像素。
      - controllers: Token 的控制者列表,即监管者列表
      

    返回值:

    ​ 成功:无

    ​ 失败:抛出异常

    main

    • 负责数据写入,其中包含了 setDocumentcreateTranchetransferWithDatatransferFromWithDatatransferFromToTranchetransferTranchetransferToTranchetransfersToTranchecontrollerTransfercontrollerRedeemauthorizeOperatorrevokeOperatorauthorizeOperatorForTrancherevokeOperatorForTrancheoperatorTransferTrancheoperatorRedeemTrancheissueissueToTrancheredeemredeemFromredeemTrancheredeemFromTranchetransferapproveapproveTranchetransferFrom 等接口。

    • 函数体

      function main(input_str){
          let input = JSON.parse(input_str);
      
          if (input.method === 'setDocument'){
            setDocument(input.params.name, input.params.url, input.params.hashType, input.params.documentHash);
          }
          else if(input.method === 'createTranche'){
            createTranche(input.params.tranche);
          }
          else if(input.method === 'changeOwnership'){
            changeOwnership(input.params.owner);
          }
          else if(input.method === 'issue'){
            issue(input.params.tokenHolder, input.params.nowSupply, input.params.data);
          }
          else if(input.method === 'issueToTranche'){
            issueToTranche(input.params.tranche, input.params.tokenHolder, input.params.nowSupply, input.params.data);
          }
          else if (input.method === 'approveTranche'){
            approveTranche(input.params.tranche, input.params.spender, input.params.value, input.params.data);
          }
          else if(input.method === 'approve'){
            approve(input.params.spender, input.params.value);
          }
          else if(input.method === 'transfer'){
            transfer(input.params.to, input.params.value);
          }
          else if(input.method === 'transferFrom'){
            transferFrom(input.params.from, input.params.to, input.params.value);
          }
          else if(input.method === 'transferWithData'){
            transferWithData(input.params.to, input.params.value, input.params.data);
          }
          else if(input.method === 'transferFromWithData'){
            transferFromWithData(input.params.from, input.params.to, input.params.value, input.params.data);
          }
          else if(input.method === 'transferTranche'){
            transferTranche(input.params.tranche, input.params.to, input.params.value, input.params.data);
          }
          else if(input.method === 'transferToTranche'){
            transferToTranche(input.params.fromTranche, input.params.to ,input.params.toTranche, input.params.value, input.params.data);
          }
          else if(input.method === 'transfersToTranche'){
            transfersToTranche(input.params.fromTranche, input.params.toTranche, input.params.tokenHolders);
          }
          else if(input.method === 'transferFromToTranche'){
            transferFromToTranche(input.params.from, input.params.fromTranche, input.params.to ,input.params.toTranche, input.params.value, input.params.data);
          }
          else if (input.method === 'controllerTransfer'){
            controllerTransfer(input.params.from, input.params.fromTranche, input.params.to, input.params.toTranche, input.params.value, input.params.data, input.params.operatorData);
          }
          else if(input.method === 'controllerRedeem'){
            controllerRedeem(input.params.tokenHolder, input.params.tranche, input.params.value, input.params.data, input.params.operatorData);
          }
          else if(input.method === 'authorizeOperator'){
            authorizeOperator(input.params.operator);
          }
          else if(input.method === 'authorizeOperatorForTranche'){
            authorizeOperatorForTranche(input.params.tranche, input.params.operator);
          }
          else if(input.method === 'revokeOperator'){
            revokeOperator(input.params.operator);
          }
          else if(input.method === 'revokeOperatorForTranche'){
            revokeOperatorForTranche(input.params.tranche, input.params.operator);
          }
          else if(input.method === 'operatorTransferTranche'){
            operatorTransferTranche(input.params.tranche, input.params.from, input.params.to, input.params.value, input.params.data, input.params.operatorData);
          }
          else if(input.method === 'redeem'){
            redeem(input.params.value, input.params.data);
          }
          else if(input.method === 'redeemFrom'){
            redeemFrom(input.params.tokenHolder, input.params.value, input.params.data);
          }
          else if(input.method === 'redeemTranche'){
            redeemTranche(input.params.tranche, input.params.value, input.params.data);
          }
          else if(input.method === 'operatorRedeemTranche'){
            operatorRedeemTranche(input.params.tranche, input.params.tokenHolder, input.params.value, input.params.operatorData);
          }
          else{
              throw '<unidentified operation type>';
          }
      }
      

    query

    • 负责数据查询,其中包含了 getDocumentisIssuabletokenInfobalanceOftranchesOfbalanceOfTrancheallowanceallowanceForTrancheisControllableisOperatorisOperatorForTranchecanTransfercanTransferTranchecanTransferToTranche 等接口。

    • 函数体

      function query(input_str){
          let result = {};
          let input  = JSON.parse(input_str);
      
          if(input.method === 'getDocument'){
            result.document = getDocument(input.params.name);
          }
          else if(input.method === 'isIssuable'){
            result.isIssuable = isIssuable();
          }
          else if(input.method === 'tokenInfo'){
            globalAttribute = JSON.parse(storageLoad(globalAttributeKey));
            result.tokenInfo = globalAttribute;
          }
          else if(input.method === 'balanceOf'){
            result.balance = balanceOf(input.params.address);
          }
          else if(input.method === 'tranchesOf'){
            result.tranches = tranchesOf(input.params.address);
          }
          else if(input.method === 'balanceOfTranche'){
            result.balance = balanceOfTranche(input.params.tranche, input.params.address);
          }
          else if(input.method === 'allowance'){
            result.allowance = allowance(input.params.owner, input.params.spender);
          }
          else if (input.method === 'allowanceForTranche'){
            result.allowance = allowanceForTranche(input.params.tranche, input.params.owner, input.params.spender);
          }
          else if(input.method === 'isControllable'){
            result.isControllable = isControllable();
          }
          else if(input.method === 'isOperator'){
            result.isOperator = isOperator(input.params.operator, input.params.tokenHolder);
          }
          else if(input.method === 'isOperatorForTranche'){
            result.isOperator = isOperatorForTranche(input.params.tranche, input.params.operator, input.params.tokenHolder);
          }
          else if(input.method === 'canTransfer'){
            result.canTransfer = canTransfer(input.params.from, input.params.to, input.params.value, input.params.data);
          }
          else if(input.method === 'canTransferTranche'){
            result.canTransfer = canTransferTranche(input.params.from, input.params.to, input.params.tranche, input.params.value, input.params.data);
          }
          else if (input.method === 'canTransferToTranche'){
            result.canTransfer = canTransferToTranche(input.params.from, input.params.fromTranche, input.params.to, input.params.toTranche, input.params.value, input.params.data);
          }
          else{
              throw '<Query interface passes an invalid operation type>';
          }
          return JSON.stringify(result);
      }
  • 相关阅读:
    Codeforces 1354C2
    Codeforces 1354C1
    Codeforces 1355C
    Codeforces 1353D
    Codeforces 1352
    Codeforces 1351C
    Codeforces 1344B/1345D
    Codeforces 1342D
    Codeforces 1340B/1341D
    Codeforces 1343D
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13313241.html
Copyright © 2020-2023  润新知