Bytom 交易说明(账户管理模式)

2018-08-24 10:32:42 +08:00
 Bytom

比原项目仓库:

Github 地址: https://github.com/Bytom/bytom

Gitee 地址: https://gitee.com/BytomBlockchain/bytom

该部分主要针对用户使用 bytom 自带的账户模式发送交易

1、构建交易

API 接口 build-transaction,代码api/transact.go#L120

以标准的非 BTM 资产转账交易为例,资产 ID 为全 F 表示 BTM 资产,在该示例中 BTM 资产仅作为手续费,该交易表示花费 99 个特定的资产到指定地址中。其中构建交易的输入请求 json 格式如下:

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 20000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 99,
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
      "type": "spend_account"
    },
    {
      "amount": 99,
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
      "type": "control_address"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

对应源代码的请求对象如下:

// BuildRequest is main struct when building transactions
type BuildRequest struct {
	Tx        *types.TxData            `json:"base_transaction"`
	Actions   []map[string]interface{} `json:"actions"`
	TTL       json.Duration            `json:"ttl"`
	TimeRange uint64                   `json:"time_range"`
}

结构字段说明如下:

注意事项


action 简介

下面对构建交易时用到的各种action类型进行详细说明:

issue

issueAction结构体源代码如下:

type issueAction struct {
	assets *Registry
	bc.AssetAmount
}

type AssetAmount struct {
	AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
	Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
}

结构字段说明如下:

issueActionjson格式为:

{
  "amount": 100000000,
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
  "type": "issue"
}

例如发行一笔资产的交易示例如下: (该交易表示发行数量为900000000assetID42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f的资产到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费为20000000neu 的 BTM 资产)

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 20000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "amount": 900000000,
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
      "type": "issue"
    },
    {
      "amount": 900000000,
      "asset_id": "42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f",
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
      "type": "control_address"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

spend_account

spendAction结构体源代码如下:

type spendAction struct {
	accounts *Manager
	bc.AssetAmount
	AccountID   string  `json:"account_id"`
	ClientToken *string `json:"client_token"`
}

type AssetAmount struct {
	AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
	Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
}

结构字段说明如下:

spendActionjson格式为:

{
  "account_id": "0BF63M2U00A04",
  "amount": 2000000000,
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  "type": "spend_account"
}

例如转账一笔资产的交易示例如下: (该交易表示通过账户的方式转账100000000neu 的 BTM 资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费20000000neu = 输入 BTM 资产数量 - 输出 BTM 资产数量)

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 120000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "amount": 100000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
      "type": "control_address"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

spend_account_unspent_output

spendUTXOAction结构体源代码如下:

type spendUTXOAction struct {
	accounts *Manager
	OutputID *bc.Hash `json:"output_id"`
	ClientToken *string `json:"client_token"`
}

结构字段说明如下:

spendUTXOActionjson格式为:

{
  "type": "spend_account_unspent_output",
  "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"
}

例如通过花费 UTXO 的方式转账一笔资产的交易示例如下: (该交易表示通过直接花费 UTXO 的方式转账100000000neu 的 BTM 资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中手续费 = 输入 BTM 资产的 UTXO 值 - 输出 BTM 资产数量)

{
  "base_transaction": null,
  "actions": [
    {
      "output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9",
      "type": "spend_account_unspent_output"
    },
    {
      "amount": 100000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
      "type": "control_address"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

control_address

controlAddressAction结构体源代码如下:

type controlAddressAction struct {
	bc.AssetAmount
	Address string `json:"address"`
}

type AssetAmount struct {
	AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
	Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
}

结构字段说明如下:

controlAddressActionjson格式为:

{
  "amount": 100000000,
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  "address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",
  "type": "control_address"
}

例如转账一笔资产的交易示例如下: (该交易表示通过账户的方式转账100000000neu 的 BTM 资产到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me中, 其中control_address类型表示以地址作为接收方式)

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 120000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "amount": 100000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "address": "sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me",
      "type": "control_address"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

control_program

controlProgramAction结构体源代码如下:

type controlProgramAction struct {
	bc.AssetAmount
	Program json.HexBytes `json:"control_program"`
}

type AssetAmount struct {
	AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
	Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
}

结构字段说明如下:

controlProgramActionjson格式为:

{
  "amount": 100000000,
  "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  "control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
  "type": "control_program"
}

例如转账一笔资产的交易示例如下: (该交易表示通过账户的方式转账100000000neu 的 BTM 资产到接收program(跟address是一一对应的)0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19中, 其中control_program类型表示以program作为接收方式)

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 120000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "amount": 100000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "control_program": "0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
      "type": "control_program"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

retire

retireAction结构体源代码如下:

type retireAction struct {
	bc.AssetAmount
}

type AssetAmount struct {
	AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
	Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
}

结构字段说明如下:

retireActionjson格式为:

{
  "amount": 900000000,
  "asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
  "type": "retire"
}

例如销毁一笔资产的交易示例如下: (该交易表示通过账户的方式将100000000neu 的 BTM 资产销毁, retire表示销毁指定数量的资产)

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ER7MEFGG0A02",
      "amount": 120000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "amount": 100000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "retire"
    }
  ],
  "ttl": 0,
  "time_range": 0
}

build-transaction的输入构造完成之后,便可以通过 http 的调用方式进行发送交易,构建交易请求成功之后返回的 json 结果如下:

{
  "allow_additional_actions": false,
  "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
  "signing_instructions": [
    {
      "position": 0,
      "witness_components": [
        {
          "keys": [
            {
              "derivation_path": [
                "010100000000000000",
                "0100000000000000"
              ],
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
            }
          ],
          "quorum": 1,
          "signatures": null,
          "type": "raw_tx_signature"
        },
        {
          "type": "data",
          "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
        }
      ]
    },
    {
      "position": 1,
      "witness_components": [
        {
          "keys": [
            {
              "derivation_path": [
                "010100000000000000",
                "0800000000000000"
              ],
              "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
            }
          ],
          "quorum": 1,
          "signatures": null,
          "type": "raw_tx_signature"
        },
        {
          "type": "data",
          "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
        }
      ]
    }
  ]
}

对应响应对象的源代码如下:

// Template represents a partially- or fully-signed transaction.
type Template struct {
	Transaction         *types.Tx             `json:"raw_transaction"`
	SigningInstructions []*SigningInstruction `json:"signing_instructions"`

	// AllowAdditional affects whether Sign commits to the tx sighash or
	// to individual details of the tx so far. When true, signatures
	// commit to tx details, and new details may be added but existing
	// ones cannot be changed. When false, signatures commit to the tx
	// as a whole, and any change to the tx invalidates the signature.
	AllowAdditional bool `json:"allow_additional_actions"`
}

结构字段说明如下:


估算手续费

估算手续费接口estimate-transaction-gas是对build-transaction的结果进行手续费的预估,估算的结果需要重新加到build-transaction的结果中,然后对交易进行签名和提交。其主要流程如下:

  build - estimate - build - sign - submit

估算手续费的输入请求 json 格式如下:

{
  "transaction_template": {
    "allow_additional_actions": false,
    "raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a077301000161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf456010003013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
    "signing_instructions": [
      {
        "position": 0,
        "witness_components": [
          {
            "keys": [
              {
                "derivation_path": [
                  "010100000000000000",
                  "0100000000000000"
                ],
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
              }
            ],
            "quorum": 1,
            "signatures": null,
            "type": "raw_tx_signature"
          },
          {
            "type": "data",
            "value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
          }
        ]
      },
      {
        "position": 1,
        "witness_components": [
          {
            "keys": [
              {
                "derivation_path": [
                  "010100000000000000",
                  "0800000000000000"
                ],
                "xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
              }
            ],
            "quorum": 1,
            "signatures": null,
            "type": "raw_tx_signature"
          },
          {
            "type": "data",
            "value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
          }
        ]
      }
    ]
  }
}

对应响应对象的源代码如下:

type request struct{
	TxTemplate txbuilder.Template `json:"transaction_template"`
}

// Template represents a partially- or fully-signed transaction.
type Template struct {
	Transaction         *types.Tx             `json:"raw_transaction"`
	SigningInstructions []*SigningInstruction `json:"signing_instructions"`

	// AllowAdditional affects whether Sign commits to the tx sighash or
	// to individual details of the tx so far. When true, signatures
	// commit to tx details, and new details may be added but existing
	// ones cannot be changed. When false, signatures commit to the tx
	// as a whole, and any change to the tx invalidates the signature.
	AllowAdditional bool `json:"allow_additional_actions"`
}

其中TxTemplate相关字段的说明见 build-transaction 的结果描述

调用estimate-transaction-gas接口成功之后返回的 json 结果如下:

{
  "total_neu": 5000000,
  "storage_neu": 3840000,
  "vm_neu": 1419000
}

对应响应对象的源代码如下:

// EstimateTxGasResp estimate transaction consumed gas
type EstimateTxGasResp struct {
	TotalNeu   int64 `json:"total_neu"`
	StorageNeu int64 `json:"storage_neu"`
	VMNeu      int64 `json:"vm_neu"`
}

结构字段说明如下:

1090 次点击
所在节点    区块链
1 条回复
Bytom
2018-08-24 10:35:01 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/482775

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX