8 "github.com/bytom/blockchain/txbuilder"
9 "github.com/bytom/crypto/ed25519/chainkd"
10 chainjson "github.com/bytom/encoding/json"
11 "github.com/bytom/protocol/bc"
12 "github.com/bytom/testutil"
15 func TestMergeSpendAction(t *testing.T) {
16 testBTM := &bc.AssetID{}
17 if err := testBTM.UnmarshalText([]byte("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); err != nil {
21 testAssetID1 := &bc.AssetID{}
22 if err := testAssetID1.UnmarshalText([]byte("50ec80b6bc48073f6aa8fa045131a71213c33f3681203b15ddc2e4b81f1f4730")); err != nil {
26 testAssetID2 := &bc.AssetID{}
27 if err := testAssetID2.UnmarshalText([]byte("43c6946d092b2959c1a82e90b282c68fca63e66de289048f6acd6cea9383c79c")); err != nil {
32 testActions []txbuilder.Action
33 wantActions []txbuilder.Action
38 testActions: []txbuilder.Action{
39 txbuilder.Action(&spendAction{
40 AssetAmount: bc.AssetAmount{
44 AccountID: "test_account",
46 txbuilder.Action(&spendAction{
47 AssetAmount: bc.AssetAmount{
51 AccountID: "test_account",
53 txbuilder.Action(&spendAction{
54 AssetAmount: bc.AssetAmount{
58 AccountID: "test_account",
60 txbuilder.Action(&spendAction{
61 AssetAmount: bc.AssetAmount{
62 AssetId: testAssetID1,
65 AccountID: "test_account",
68 wantActions: []txbuilder.Action{
69 txbuilder.Action(&spendAction{
70 AssetAmount: bc.AssetAmount{
74 AccountID: "test_account",
76 txbuilder.Action(&spendAction{
77 AssetAmount: bc.AssetAmount{
78 AssetId: testAssetID1,
81 AccountID: "test_account",
88 testActions: []txbuilder.Action{
89 txbuilder.Action(&spendAction{
90 AssetAmount: bc.AssetAmount{
94 AccountID: "test_account",
96 txbuilder.Action(&spendAction{
97 AssetAmount: bc.AssetAmount{
98 AssetId: testAssetID1,
101 AccountID: "test_account",
103 txbuilder.Action(&spendAction{
104 AssetAmount: bc.AssetAmount{
108 AccountID: "test_account",
110 txbuilder.Action(&spendAction{
111 AssetAmount: bc.AssetAmount{
112 AssetId: testAssetID1,
115 AccountID: "test_account",
118 wantActions: []txbuilder.Action{
119 txbuilder.Action(&spendAction{
120 AssetAmount: bc.AssetAmount{
124 AccountID: "test_account",
126 txbuilder.Action(&spendAction{
127 AssetAmount: bc.AssetAmount{
128 AssetId: testAssetID1,
131 AccountID: "test_account",
138 testActions: []txbuilder.Action{
139 txbuilder.Action(&spendAction{
140 AssetAmount: bc.AssetAmount{
144 AccountID: "test_account",
146 txbuilder.Action(&spendAction{
147 AssetAmount: bc.AssetAmount{
148 AssetId: testAssetID1,
151 AccountID: "test_account",
153 txbuilder.Action(&spendAction{
154 AssetAmount: bc.AssetAmount{
155 AssetId: testAssetID2,
158 AccountID: "test_account",
160 txbuilder.Action(&spendAction{
161 AssetAmount: bc.AssetAmount{
162 AssetId: testAssetID1,
165 AccountID: "test_account",
167 txbuilder.Action(&spendAction{
168 AssetAmount: bc.AssetAmount{
169 AssetId: testAssetID2,
172 AccountID: "test_account",
175 wantActions: []txbuilder.Action{
176 txbuilder.Action(&spendAction{
177 AssetAmount: bc.AssetAmount{
181 AccountID: "test_account",
183 txbuilder.Action(&spendAction{
184 AssetAmount: bc.AssetAmount{
185 AssetId: testAssetID1,
188 AccountID: "test_account",
190 txbuilder.Action(&spendAction{
191 AssetAmount: bc.AssetAmount{
192 AssetId: testAssetID2,
195 AccountID: "test_account",
202 testActions: []txbuilder.Action{
203 txbuilder.Action(&spendAction{
204 AssetAmount: bc.AssetAmount{
208 AccountID: "test_account",
210 txbuilder.Action(&spendAction{
211 AssetAmount: bc.AssetAmount{
215 AccountID: "test_account1",
217 txbuilder.Action(&spendAction{
218 AssetAmount: bc.AssetAmount{
222 AccountID: "test_account",
224 txbuilder.Action(&spendAction{
225 AssetAmount: bc.AssetAmount{
226 AssetId: testAssetID1,
229 AccountID: "test_account1",
232 wantActions: []txbuilder.Action{
233 txbuilder.Action(&spendAction{
234 AssetAmount: bc.AssetAmount{
238 AccountID: "test_account",
240 txbuilder.Action(&spendAction{
241 AssetAmount: bc.AssetAmount{
245 AccountID: "test_account1",
247 txbuilder.Action(&spendAction{
248 AssetAmount: bc.AssetAmount{
249 AssetId: testAssetID1,
252 AccountID: "test_account1",
259 testActions: []txbuilder.Action{
260 txbuilder.Action(&spendUTXOAction{
261 OutputID: &bc.Hash{V0: 128},
263 txbuilder.Action(&spendAction{
264 AssetAmount: bc.AssetAmount{
268 AccountID: "test_account",
270 txbuilder.Action(&spendAction{
271 AssetAmount: bc.AssetAmount{
272 AssetId: testAssetID1,
275 AccountID: "test_account1",
277 txbuilder.Action(&spendUTXOAction{
278 OutputID: &bc.Hash{V0: 256},
280 txbuilder.Action(&spendAction{
281 AssetAmount: bc.AssetAmount{
282 AssetId: testAssetID2,
285 AccountID: "test_account2",
288 wantActions: []txbuilder.Action{
289 txbuilder.Action(&spendUTXOAction{
290 OutputID: &bc.Hash{V0: 128},
292 txbuilder.Action(&spendAction{
293 AssetAmount: bc.AssetAmount{
297 AccountID: "test_account",
299 txbuilder.Action(&spendAction{
300 AssetAmount: bc.AssetAmount{
301 AssetId: testAssetID1,
304 AccountID: "test_account1",
306 txbuilder.Action(&spendUTXOAction{
307 OutputID: &bc.Hash{V0: 256},
309 txbuilder.Action(&spendAction{
310 AssetAmount: bc.AssetAmount{
311 AssetId: testAssetID2,
314 AccountID: "test_account2",
322 for _, c := range cases {
323 gotActions := MergeSpendAction(c.testActions)
325 gotMap := make(map[string]uint64)
326 wantMap := make(map[string]uint64)
327 for _, got := range gotActions {
328 switch got := got.(type) {
330 gotKey := got.AssetId.String() + got.AccountID
331 gotMap[gotKey] = got.Amount
337 for _, want := range c.wantActions {
338 switch want := want.(type) {
340 wantKey := want.AssetId.String() + want.AccountID
341 wantMap[wantKey] = want.Amount
347 for key := range gotMap {
348 if gotMap[key] != wantMap[key] {
349 t.Fatalf("gotMap[%s]=%v, wantMap[%s]=%v", key, gotMap[key], key, wantMap[key])
353 if len(gotActions) != c.wantActionCount {
354 t.Fatalf("number of gotActions=%d, wantActions=%d", len(gotActions), c.wantActionCount)
359 func TestSpendUTXOArguments(t *testing.T) {
360 hexXpub, err := hex.DecodeString("ba76bb52574b3f40315f2c01f1818a9072ced56e9d4b68acbef56a4d0077d08e5e34837963e4cdc54eb251aa34aad01e6ae48b140f6a2743fbb0a0abd9cf8aac")
365 var xpub chainkd.XPub
366 copy(xpub[:], hexXpub)
368 rawTxSig := rawTxSigArgument{RootXPub: xpub, Path: []chainjson.HexBytes{{1, 1, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 0}}}
369 rawTxSigMsg, err := json.Marshal(rawTxSig)
374 data := dataArgument{Value: "7468697320697320612074657374"}
375 dataMsg, err := json.Marshal(data)
382 wantResult *spendUTXOAction
385 rawAction: `{ "type": "spend_account_unspent_output", "output_id": "e304de887423e4e684e483f5ae65236d47018b56cac94ef3fb8b5dd40c897e11",
386 "arguments": [{"type": "raw_tx_signature", "raw_data": {"derivation_path": ["010100000000000000", "0100000000000000"],
387 "xpub": "ba76bb52574b3f40315f2c01f1818a9072ced56e9d4b68acbef56a4d0077d08e5e34837963e4cdc54eb251aa34aad01e6ae48b140f6a2743fbb0a0abd9cf8aac"}}]}`,
388 wantResult: &spendUTXOAction{
389 OutputID: &bc.Hash{16358444424161912038, 9575923798912607085, 5116523856555233011, 18125684290607480337},
390 Arguments: []contractArgument{
392 Type: "raw_tx_signature",
393 RawData: rawTxSigMsg,
399 rawAction: `{ "type": "spend_account_unspent_output", "output_id": "8669b5c2e0701ec1ca45cd413e46c4f1d5f794f9d9144f904f3e7da8c68c6410",
400 "arguments": [{"type": "data", "raw_data": {"value": "7468697320697320612074657374"}}]}`,
401 wantResult: &spendUTXOAction{
402 OutputID: &bc.Hash{9685472322230689473, 14575281449155871985, 15417955650135936912, 5710139541391434768},
403 Arguments: []contractArgument{
412 rawAction: `{ "type": "spend_account_unspent_output", "output_id": "8669b5c2e0701ec1ca45cd413e46c4f1d5f794f9d9144f904f3e7da8c68c6410",
413 "arguments": [{"type": "signature", "raw_data": {"value": "7468697320697320612074657374"}}]}`,
414 wantResult: &spendUTXOAction{
415 OutputID: &bc.Hash{9685472322230689473, 14575281449155871985, 15417955650135936912, 5710139541391434768},
419 rawAction: `{ "type": "spend_account_unspent_output", "output_id": "8669b5c2e0701ec1ca45cd413e46c4f1d5f794f9d9144f904f3e7da8c68c6410"}`,
420 wantResult: &spendUTXOAction{
421 OutputID: &bc.Hash{9685472322230689473, 14575281449155871985, 15417955650135936912, 5710139541391434768},
427 for _, c := range cases {
428 var spendUTXOReq *spendUTXOAction
429 if err := json.Unmarshal([]byte(c.rawAction), &spendUTXOReq); err != nil {
430 t.Fatalf("unmarshal spendUTXOAction error:%v", err)
433 if !testutil.DeepEqual(spendUTXOReq.OutputID, c.wantResult.OutputID) {
434 t.Fatalf("OutputID gotResult=%v, wantResult=%v", spendUTXOReq.OutputID, c.wantResult.OutputID)
437 if spendUTXOReq.Arguments == nil {
438 if c.wantResult.Arguments != nil {
439 t.Fatalf("Arguments gotResult is nil, wantResult[%v] is not nil", c.wantResult.Arguments)
444 for _, arg := range spendUTXOReq.Arguments {
446 case "raw_tx_signature":
447 rawTxSig := &rawTxSigArgument{}
448 if err := json.Unmarshal(arg.RawData, rawTxSig); err != nil {
449 t.Fatalf("unmarshal rawTxSigArgument error:%v", err)
452 wantRawTxSig := &rawTxSigArgument{}
453 if err := json.Unmarshal(c.wantResult.Arguments[0].RawData, wantRawTxSig); err != nil {
454 t.Fatalf("unmarshal want rawTxSigArgument error:%v", err)
457 if !testutil.DeepEqual(rawTxSig, wantRawTxSig) {
458 t.Fatalf("rawTxSigArgument gotResult=%v, wantResult=%v", rawTxSig, wantRawTxSig)
462 data := &dataArgument{}
463 if err := json.Unmarshal(arg.RawData, data); err != nil {
464 t.Fatalf("unmarshal dataArgument error:%v", err)
467 wantData := &dataArgument{}
468 if err := json.Unmarshal(c.wantResult.Arguments[0].RawData, wantData); err != nil {
469 t.Fatalf("unmarshal want dataArgument error:%v", err)
472 if !testutil.DeepEqual(data, wantData) {
473 t.Fatalf("dataArgument gotResult=%v, wantResult=%v", data, wantData)
477 if arg.Type == "raw_tx_signature" || arg.Type == "data" {
478 t.Fatalf("argument type [%v] is not exist", arg.Type)