該部分主要針對使用者使用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"`
}
結構欄位說明如下:
-
Tx
交易的TxData
部分,該欄位為預留欄位,為空即可 -
TTL
構建交易的生存時間(單位為毫秒),意味著在該時間範圍內,已經快取的utxo不能用於再一次build交易,除非剩餘的utxo足以構建一筆新的交易,否則會報錯。當ttl
為0時會被預設設定為600s,即5分鐘 -
TimeRange
時間戳,意味著該交易將在該時間戳(區塊高度)之後不會被提交上鍊,為了防止交易在網路中傳輸延遲而等待太久時間,如果交易沒有在特定的時間範圍內被打包,該交易便會自動失效 -
Actions
交易的actions
結構,所有的交易都是由action構成的,map
型別的interface{}
保證了action型別的可擴充套件性。其中action中必須包含type欄位,用於區分不同的action型別,action
主要包含input
和output
兩種型別,其詳細介紹如下:-
input action
型別:- issue 發行資產
- spend_account 以賬戶的模式花費utxo
- spend_account_unspent_output 直接花費指定的utxo
-
output action
型別:- control_address 接收方式為地址模式
- control_program 接收方式為(program)合約模式
- retire 銷燬資產
-
注意事項:
- 一個交易必須至少包含一個input和output(coinbase交易除外,因為coinbase交易是由系統產生,故不在此加以描述),否則交易將會報錯。
- 除了BTM資產(所有交易都是以BTM資產作為手續費)之外,其他資產在構建input和output時,所有輸入和輸出的資產總和必須相等,否則交易會報出輸入輸出不平衡的錯誤資訊。
- 交易的手續費: 所有inputs的BTM資產數量 – 所有outputs的BTM資產數量
- 交易中的資產amount都是neu為單位的,BTM的單位換算如下:1 BTM = 1000 mBTM = 100000000 neu
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"`
}
結構欄位說明如下:
-
assets
主要用於資產的管理,無需使用者設定引數 -
AssetAmount
表示使用者需要發行的資產ID和對應的資產數目,這裡的AssetID
需要通過create-asset
建立,並且這裡不能使用BTM
的資產ID
issueAction
的json
格式為:
{
"amount": 100000000,
"asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
"type": "issue"
}
例如發行一筆資產的交易示例如下:
(該交易表示發行數量為900000000
個assetID
的42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f
的資產到接收地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me
中, 其中手續費為20000000
neu的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"`
}
結構欄位說明如下:
-
accounts
主要用於賬戶的管理,無需使用者設定引數 -
AccountID
表示需要花費資產的賬戶ID -
AssetAmount
表示花費的資產ID和對應的資產數目 -
ClientToken
表示Reserve使用者UTXO的限制條件,目前不填或為空即可
spendAction
的json
格式為:
{
"account_id": "0BF63M2U00A04",
"amount": 2000000000,
"asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"type": "spend_account"
}
例如轉賬一筆資產的交易示例如下:
(該交易表示通過賬戶的方式轉賬100000000
neu的BTM資產到地址sm1qxe4jwhkekgnxkezu7xutu5gqnnpmyc8ppq98me
中, 其中手續費20000000
neu = 輸入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"`
}
結構欄位說明如下:
-
accounts
主要用於賬戶的管理,無需使用者設定引數 -
OutputID
表示需要花費的UTXO的ID,可以根據list-unspent-outputs
查詢可用的UTXO,其中OutputID
對應該API返回結果的id
欄位 -
ClientToken
表示Reserve使用者UTXO的限制條件,目前不填或為空即可
spendUTXOAction
的json
格式為:
{
"type": "spend_account_unspent_output",
"output_id": "58f29f0f85f7bd2a91088bcbe536dee41cd0642dfb1480d3a88589bdbfd642d9"
}
例如通過花費UTXO的方式轉賬一筆資產的交易示例如下:
(該交易表示通過直接花費UTXO的方式轉賬100000000
neu的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"`
}
結構欄位說明如下:
-
Address
表示接收資產的地址,可以根據create-account-receiver
API介面建立地址 -
AssetAmount
表示接收的資產ID和對應的資產數目
controlAddressAction
的json
格式為:
{
"amount": 100000000,
"asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"address": "bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68",
"type": "control_address"
}
例如轉賬一筆資產的交易示例如下:
(該交易表示通過賬戶的方式轉賬100000000
neu的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"`
}
結構欄位說明如下:
-
Program
表示接收資產的合約指令碼,可以根據create-account-receiver
API介面建立接收program
(返回結果的program
和address
是一一對應的) -
AssetAmount
表示接收的資產ID和對應的資產數目
controlProgramAction
的json
格式為:
{
"amount": 100000000,
"asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"control_program":"0014a3f9111f3b0ee96cbd119a3ea5c60058f506fb19",
"type": "control_program"
}
例如轉賬一筆資產的交易示例如下:
(該交易表示通過賬戶的方式轉賬100000000
neu的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"`
}
結構欄位說明如下:
-
AssetAmount
表示銷燬的資產ID和對應的資產數目
retireAction
的json
格式為:
{
"amount": 900000000,
"asset_id": "3152a15da72be51b330e1c0f8e1c0db669269809da4f16443ff266e07cc43680",
"type": "retire"
}
例如銷燬一筆資產的交易示例如下:
(該交易表示通過賬戶的方式將100000000
neu的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"`
}
結構欄位說明如下:
-
Transaction
交易相關資訊,該欄位包含TxData
和bc.Tx
兩個部分:-
TxData
表示給使用者展示的交易資料部分,該部分對使用者可見-
Version
交易版本 -
SerializedSize
交易序列化之後的size -
TimeRange
交易提交上鍊的最大時間戳(區塊高度)(主鏈區塊高度到達該時間戳(區塊高度)之後,如果交易沒有被提交上鍊,該交易便會失效) -
Inputs
交易輸入 -
Outputs
交易輸出
-
-
bc.Tx
表示系統中處理交易用到的轉換結構,該部分對使用者不可見,故不做詳細描述
-
-
SigningInstructions
交易的簽名資訊-
Position
對input action
簽名的位置 -
WitnessComponents
對input action
簽名需要的資料資訊,其中build交易的signatures
為null
,表示沒有簽名; 如果交易簽名成功,則該欄位會存在簽名資訊。該欄位是一個interface介面,主要包含3種不同的型別:-
SignatureWitness
對交易模板Template
中交易input action
位置的合約program進行雜湊,然後對hash值進行簽名-
signatures
(陣列型別)交易的簽名,sign-transaction
執行完成之後才會有值存在 -
keys
(陣列型別)包含主公鑰xpub
和派生路徑derivation_path
,通過它們可以在簽名階段找到對應的派生私鑰child_xprv
,然後使用派生私鑰進行簽名 -
quorum
賬戶key
的個數,必須和上面的keys
的長度相等。如果quorum
等於1,則表示單籤賬戶,否則為多籤賬戶 -
program
簽名的資料部分,program
的hash值作為簽名資料。如果program
為空,則會根據當前交易ID和對應action位置的InputID兩部分生成一個hash,然後把它們作為指令資料自動構造一個program
-
-
RawTxSigWitness
對交易模板Template
的交易ID和對應input action
位置的InputID(該欄位位於bc.Tx中)進行雜湊,然後對hash值進行簽名-
signatures
(陣列型別)交易的簽名,sign-transaction
執行完成之後才會有值存在 -
keys
(陣列型別)包含主公鑰xpub
和派生路徑derivation_path
,通過它們可以在簽名階段找到對應的派生私鑰child_xprv
,然後使用派生私鑰進行簽名 -
quorum
賬戶key
的個數,必須和上面的keys
的長度相等。如果quorum
等於1,則表示單籤賬戶,否則為多籤賬戶
-
-
DataWitness
該型別無需簽名,驗證合約program的附加資料
-
-
-
AllowAdditional
是否允許交易的附加資料,如果為true
,則交易的附加資料會新增到交易中,但是不會影響交易的執行的program
指令碼,對簽名結果不會造成影響; 如果為false
,則整個交易作為一個整體進行簽名,任何資料的改變將影響整個交易的簽名
估算手續費
估算手續費介面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"`
}
結構欄位說明如下:
-
TotalNeu
預估的總手續費(單位為neu),該值直接加到build-transaction的BTM資產輸入action中即可 -
StorageNeu
儲存交易的手續費 -
VMNeu
執行虛擬機器的手續費
2、簽名交易
API介面 sign-transaction,程式碼api/hsm.go#L53
簽名交易的輸入請求json格式如下:
{
"password": "123456",
"transaction": {
"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 SignRequest struct { //function pseudohsmSignTemplates request
Password string `json:"password"`
Txs txbuilder.Template `json:"transaction"`
}
結構欄位說明如下:
-
Password
簽名的密碼,根據密碼可以從節點伺服器上解析出使用者的私鑰,然後用私鑰對交易進行簽名 -
Txs
交易模板,build-transaction的返回結果,結構型別為txbuilder.Template
,相關欄位的說明見build-transaction的結果描述
簽名交易sign-transaction
請求成功之後返回的json結果如下:
{
"sign_complete": true,
"transaction": {
"allow_additional_actions": false,
"raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100",
"signing_instructions": [
{
"position": 0,
"witness_components": [
{
"keys": [
{
"derivation_path": [
"010100000000000000",
"0100000000000000"
],
"xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
}
],
"quorum": 1,
"signatures": [
"273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e38806"
],
"type": "raw_tx_signature"
},
{
"type": "data",
"value": "d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd5"
}
]
},
{
"position": 1,
"witness_components": [
{
"keys": [
{
"derivation_path": [
"010100000000000000",
"0800000000000000"
],
"xpub": "de0db655c091b2838ccb6cddb675779b0a9a4204b122e61699b339867dd10eb0dbdc926882ff6dd75c099c181c60d63eab0033a4b0a4d0a8c78079e39d7ad1d8"
}
],
"quorum": 1,
"signatures": [
"0cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d"
],
"type": "raw_tx_signature"
},
{
"type": "data",
"value": "05cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe61540535419"
}
]
}
]
}
}
對應響應物件的原始碼如下:
type signResp struct {
Tx *txbuilder.Template `json:"transaction"`
SignComplete bool `json:"sign_complete"`
}
結構欄位說明如下:
-
Tx
簽名之後的交易模板txbuilder.Template
,如果簽名成功則signatures
會由null變成簽名的值,而raw_transaction
的長度會變長,是因為bc.Tx
部分新增了驗證簽名的引數資訊 -
SignComplete
簽名是否完成標誌,如果為true
表示簽名完成,否則為false
表示簽名未完成,單籤的話一般可能為簽名密碼錯誤; 而多籤的話一般為還需要其他簽名。簽名失敗只需將簽名的交易資料用正確的密碼重新簽名即可,無需再次build-transaction
構建交易
3、提交交易
API介面 submit-transaction,程式碼api/transact.go#L135
提交交易的輸入請求json格式如下:
{
"raw_transaction": "070100020161015f1190c60818b4aff485c865113c802942f29ce09088cae1b117fc4c8db2292212ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8099c4d599010001160014a86c83ee12e6d790fb388345cc2e2b87056a0773630240273d5fc4fb06909fbc2968ea91c411fd20f690c88e74284ce2732052400129948538562fe432afd6cf17e590e8645b80edf80b9d9581d0a980d5f9f859e3880620d174db6506e35f2decb5be148c2984bfd0f6c67f043365bf642d1af387c04fd50161015fb018097c4040c8dd86d95611a13c24f90d4c9d9d06b25f5c9ed0556ac8abd73442275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f80a094a58d1d0101160014068840e56af74038571f223b1c99f1b60caaf4566302400cf0beefceaf9fbf1efadedeff7aee5b38ee7a25a20d78b630b01613bc2f8c9230555a6e09aaa11a82ba68c0fc9e98a47c852dfe3de851d93f9b2b7ce256f90d2005cdbcc705f07ad87521835bbba226ad7b430cc24e5e3f008edbe6154053541903013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80bfffcb9901011600140b946646626c55a52a325c8bb48de792284d9b7200013e42275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f9d9f94a58d1d01160014c8b4391bab4923a83b955170d24ee4ca5b6ec3fb00013942275aacbeda1522cd41580f875c3c452daf5174b17ba062bf0ab71a568c123f6301160014366b275ed9b2266b645cf1b8be51009cc3b260e100"
}
對應原始碼的請求物件如下:
type SubmitRequest struct { //function submit request
Tx types.Tx `json:"raw_transaction"`
}
結構欄位說明如下:
-
Tx
簽名完成之後的交易資訊。這裡需要注意該欄位中的raw_transaction
不是簽名交易sign-transaction
的全部返回結果,而是簽名交易返回結果中transaction
中的raw_transaction
欄位。
submit-transaction
請求成功之後返回的json結果如下:
{
"tx_id": "2c0624a7d251c29d4d1ad14297c69919214e78d995affd57e73fbf84ece361cd"
}
對應原始碼的響應物件如下:
type submitTxResp struct {
TxID *bc.Hash `json:"tx_id"`
}
結構欄位說明如下:
-
TxID
交易ID,當交易被提交到交易池之後會顯示該資訊,否則表示交易失敗