7 "github.com/bytom/vapor/blockchain/txbuilder"
8 "github.com/bytom/vapor/consensus"
9 "github.com/bytom/vapor/errors"
10 "github.com/bytom/vapor/protocol/bc"
11 "github.com/bytom/vapor/protocol/bc/types"
14 type SpendAccountAction struct {
15 AccountID string `json:"account_id"`
19 func (s *SpendAccountAction) MarshalJSON() ([]byte, error) {
20 return json.Marshal(&struct {
21 Type string `json:"type"`
22 AccountID string `json:"account_id"`
25 Type: "spend_account",
26 AccountID: s.AccountID,
27 AssetAmount: s.AssetAmount,
31 type ControlAddressAction struct {
32 Address string `json:"address"`
36 func (c *ControlAddressAction) MarshalJSON() ([]byte, error) {
37 return json.Marshal(&struct {
38 Type string `json:"type"`
39 Address string `json:"address"`
42 Type: "control_address",
44 AssetAmount: c.AssetAmount,
48 type RetireAction struct {
53 func (r *RetireAction) MarshalJSON() ([]byte, error) {
54 return json.Marshal(&struct {
55 Type string `json:"type"`
56 Arbitrary string `json:"arbitrary"`
60 Arbitrary: hex.EncodeToString(r.Arbitrary),
61 AssetAmount: r.AssetAmount,
65 func (n *Node) BatchSendBTM(accountID, password string, outputs map[string]uint64, memo []byte) (string, error) {
66 totalBTM := uint64(1000000)
67 actions := []interface{}{}
69 actions = append(actions, &RetireAction{
71 AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: 1},
75 for address, amount := range outputs {
76 actions = append(actions, &ControlAddressAction{
78 AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: amount},
83 actions = append(actions, &SpendAccountAction{
85 AssetAmount: &bc.AssetAmount{AssetId: consensus.BTMAssetID, Amount: totalBTM},
88 tpl, err := n.buildTx(actions)
93 tpl, err = n.signTx(tpl, password)
98 return n.SubmitTx(tpl.Transaction)
101 type buildTxReq struct {
102 Actions []interface{} `json:"actions"`
105 func (n *Node) buildTx(actions []interface{}) (*txbuilder.Template, error) {
106 url := "/build-transaction"
107 payload, err := json.Marshal(&buildTxReq{Actions: actions})
109 return nil, errors.Wrap(err, "Marshal spend request")
112 result := &txbuilder.Template{}
113 return result, n.request(url, payload, result)
116 func (n *Node) BuildChainTxs(actions []interface{}) ([]*txbuilder.Template, error) {
117 url := "/build-chain-transactions"
119 payload, err := json.Marshal(&buildTxReq{Actions: actions})
121 return nil, errors.Wrap(err, "Marshal spend request")
124 result := []*txbuilder.Template{}
125 return result, n.request(url, payload, &result)
128 type signTxReq struct {
129 Tx *txbuilder.Template `json:"transaction"`
130 Password string `json:"password"`
133 type signTxResp struct {
134 Tx *txbuilder.Template `json:"transaction"`
135 SignComplete bool `json:"sign_complete"`
138 func (n *Node) signTx(tpl *txbuilder.Template, password string) (*txbuilder.Template, error) {
139 url := "/sign-transaction"
140 payload, err := json.Marshal(&signTxReq{Tx: tpl, Password: password})
142 return nil, errors.Wrap(err, "json marshal")
145 resp := &signTxResp{}
146 if err := n.request(url, payload, resp); err != nil {
150 if !resp.SignComplete {
151 return nil, errors.New("sign fail")
157 type signTxsReq struct {
158 Txs []*txbuilder.Template `json:"transactions"`
159 Password string `json:"password"`
162 type signTxsResp struct {
163 Txs []*txbuilder.Template `json:"transaction"`
164 SignComplete bool `json:"sign_complete"`
167 func (n *Node) SignTxs(tpls []*txbuilder.Template, password string) ([]*txbuilder.Template, error) {
168 url := "/sign-transactions"
169 payload, err := json.Marshal(&signTxsReq{Txs: tpls, Password: password})
171 return nil, errors.Wrap(err, "json marshal")
174 resp := &signTxsResp{}
175 if err := n.request(url, payload, resp); err != nil {
179 if !resp.SignComplete {
180 return nil, errors.New("sign fail")
186 type submitTxReq struct {
187 Tx *types.Tx `json:"raw_transaction"`
190 type submitTxResp struct {
191 TxID string `json:"tx_id"`
194 func (n *Node) SubmitTx(tx *types.Tx) (string, error) {
195 url := "/submit-transaction"
196 payload, err := json.Marshal(submitTxReq{Tx: tx})
198 return "", errors.Wrap(err, "json marshal")
201 res := &submitTxResp{}
202 return res.TxID, n.request(url, payload, res)
205 type submitTxsReq struct {
206 Txs []*types.Tx `json:"raw_transactions"`
209 type submitTxsResp struct {
210 TxsID []string `json:"tx_id"`
213 func (n *Node) SubmitTxs(txs []*types.Tx) ([]string, error) {
214 url := "/submit-transactions"
215 payload, err := json.Marshal(submitTxsReq{Txs: txs})
217 return []string{}, errors.Wrap(err, "json marshal")
220 res := &submitTxsResp{}
221 return res.TxsID, n.request(url, payload, res)