@@ -349,6 +349,188 @@ func TestInputVariableInputLength(t *testing.T) {
349
349
}
350
350
}
351
351
352
+ func TestInputFixedArrayAndVariableInputLength (t * testing.T ) {
353
+ const definition = `[
354
+ { "type" : "function", "name" : "fixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] },
355
+ { "type" : "function", "name" : "fixedArrBytes", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] },
356
+ { "type" : "function", "name" : "mixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type": "uint256[2]" }, { "name" : "dynArr", "type": "uint256[]" } ] },
357
+ { "type" : "function", "name" : "doubleFixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "fixedArr2", "type": "uint256[3]" } ] },
358
+ { "type" : "function", "name" : "multipleMixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] }
359
+ ]`
360
+
361
+ abi , err := JSON (strings .NewReader (definition ))
362
+ if err != nil {
363
+ t .Error (err )
364
+ }
365
+
366
+ // test string, fixed array uint256[2]
367
+ strin := "hello world"
368
+ arrin := [2 ]* big.Int {big .NewInt (1 ), big .NewInt (2 )}
369
+ fixedArrStrPack , err := abi .Pack ("fixedArrStr" , strin , arrin )
370
+ if err != nil {
371
+ t .Error (err )
372
+ }
373
+
374
+ // generate expected output
375
+ offset := make ([]byte , 32 )
376
+ offset [31 ] = 96
377
+ length := make ([]byte , 32 )
378
+ length [31 ] = byte (len (strin ))
379
+ strvalue := common .RightPadBytes ([]byte (strin ), 32 )
380
+ arrinvalue1 := common .LeftPadBytes (arrin [0 ].Bytes (), 32 )
381
+ arrinvalue2 := common .LeftPadBytes (arrin [1 ].Bytes (), 32 )
382
+ exp := append (offset , arrinvalue1 ... )
383
+ exp = append (exp , arrinvalue2 ... )
384
+ exp = append (exp , append (length , strvalue ... )... )
385
+
386
+ // ignore first 4 bytes of the output. This is the function identifier
387
+ fixedArrStrPack = fixedArrStrPack [4 :]
388
+ if ! bytes .Equal (fixedArrStrPack , exp ) {
389
+ t .Errorf ("expected %x, got %x\n " , exp , fixedArrStrPack )
390
+ }
391
+
392
+ // test byte array, fixed array uint256[2]
393
+ bytesin := []byte (strin )
394
+ arrin = [2 ]* big.Int {big .NewInt (1 ), big .NewInt (2 )}
395
+ fixedArrBytesPack , err := abi .Pack ("fixedArrBytes" , bytesin , arrin )
396
+ if err != nil {
397
+ t .Error (err )
398
+ }
399
+
400
+ // generate expected output
401
+ offset = make ([]byte , 32 )
402
+ offset [31 ] = 96
403
+ length = make ([]byte , 32 )
404
+ length [31 ] = byte (len (strin ))
405
+ strvalue = common .RightPadBytes ([]byte (strin ), 32 )
406
+ arrinvalue1 = common .LeftPadBytes (arrin [0 ].Bytes (), 32 )
407
+ arrinvalue2 = common .LeftPadBytes (arrin [1 ].Bytes (), 32 )
408
+ exp = append (offset , arrinvalue1 ... )
409
+ exp = append (exp , arrinvalue2 ... )
410
+ exp = append (exp , append (length , strvalue ... )... )
411
+
412
+ // ignore first 4 bytes of the output. This is the function identifier
413
+ fixedArrBytesPack = fixedArrBytesPack [4 :]
414
+ if ! bytes .Equal (fixedArrBytesPack , exp ) {
415
+ t .Errorf ("expected %x, got %x\n " , exp , fixedArrBytesPack )
416
+ }
417
+
418
+ // test string, fixed array uint256[2], dynamic array uint256[]
419
+ strin = "hello world"
420
+ fixedarrin := [2 ]* big.Int {big .NewInt (1 ), big .NewInt (2 )}
421
+ dynarrin := []* big.Int {big .NewInt (1 ), big .NewInt (2 ), big .NewInt (3 )}
422
+ mixedArrStrPack , err := abi .Pack ("mixedArrStr" , strin , fixedarrin , dynarrin )
423
+ if err != nil {
424
+ t .Error (err )
425
+ }
426
+
427
+ // generate expected output
428
+ stroffset := make ([]byte , 32 )
429
+ stroffset [31 ] = 128
430
+ strlength := make ([]byte , 32 )
431
+ strlength [31 ] = byte (len (strin ))
432
+ strvalue = common .RightPadBytes ([]byte (strin ), 32 )
433
+ fixedarrinvalue1 := common .LeftPadBytes (fixedarrin [0 ].Bytes (), 32 )
434
+ fixedarrinvalue2 := common .LeftPadBytes (fixedarrin [1 ].Bytes (), 32 )
435
+ dynarroffset := make ([]byte , 32 )
436
+ dynarroffset [31 ] = byte (160 + ((len (strin )/ 32 )+ 1 )* 32 )
437
+ dynarrlength := make ([]byte , 32 )
438
+ dynarrlength [31 ] = byte (len (dynarrin ))
439
+ dynarrinvalue1 := common .LeftPadBytes (dynarrin [0 ].Bytes (), 32 )
440
+ dynarrinvalue2 := common .LeftPadBytes (dynarrin [1 ].Bytes (), 32 )
441
+ dynarrinvalue3 := common .LeftPadBytes (dynarrin [2 ].Bytes (), 32 )
442
+ exp = append (stroffset , fixedarrinvalue1 ... )
443
+ exp = append (exp , fixedarrinvalue2 ... )
444
+ exp = append (exp , dynarroffset ... )
445
+ exp = append (exp , append (strlength , strvalue ... )... )
446
+ dynarrarg := append (dynarrlength , dynarrinvalue1 ... )
447
+ dynarrarg = append (dynarrarg , dynarrinvalue2 ... )
448
+ dynarrarg = append (dynarrarg , dynarrinvalue3 ... )
449
+ exp = append (exp , dynarrarg ... )
450
+
451
+ // ignore first 4 bytes of the output. This is the function identifier
452
+ mixedArrStrPack = mixedArrStrPack [4 :]
453
+ if ! bytes .Equal (mixedArrStrPack , exp ) {
454
+ t .Errorf ("expected %x, got %x\n " , exp , mixedArrStrPack )
455
+ }
456
+
457
+ // test string, fixed array uint256[2], fixed array uint256[3]
458
+ strin = "hello world"
459
+ fixedarrin1 := [2 ]* big.Int {big .NewInt (1 ), big .NewInt (2 )}
460
+ fixedarrin2 := [3 ]* big.Int {big .NewInt (1 ), big .NewInt (2 ), big .NewInt (3 )}
461
+ doubleFixedArrStrPack , err := abi .Pack ("doubleFixedArrStr" , strin , fixedarrin1 , fixedarrin2 )
462
+ if err != nil {
463
+ t .Error (err )
464
+ }
465
+
466
+ // generate expected output
467
+ stroffset = make ([]byte , 32 )
468
+ stroffset [31 ] = 192
469
+ strlength = make ([]byte , 32 )
470
+ strlength [31 ] = byte (len (strin ))
471
+ strvalue = common .RightPadBytes ([]byte (strin ), 32 )
472
+ fixedarrin1value1 := common .LeftPadBytes (fixedarrin1 [0 ].Bytes (), 32 )
473
+ fixedarrin1value2 := common .LeftPadBytes (fixedarrin1 [1 ].Bytes (), 32 )
474
+ fixedarrin2value1 := common .LeftPadBytes (fixedarrin2 [0 ].Bytes (), 32 )
475
+ fixedarrin2value2 := common .LeftPadBytes (fixedarrin2 [1 ].Bytes (), 32 )
476
+ fixedarrin2value3 := common .LeftPadBytes (fixedarrin2 [2 ].Bytes (), 32 )
477
+ exp = append (stroffset , fixedarrin1value1 ... )
478
+ exp = append (exp , fixedarrin1value2 ... )
479
+ exp = append (exp , fixedarrin2value1 ... )
480
+ exp = append (exp , fixedarrin2value2 ... )
481
+ exp = append (exp , fixedarrin2value3 ... )
482
+ exp = append (exp , append (strlength , strvalue ... )... )
483
+
484
+ // ignore first 4 bytes of the output. This is the function identifier
485
+ doubleFixedArrStrPack = doubleFixedArrStrPack [4 :]
486
+ if ! bytes .Equal (doubleFixedArrStrPack , exp ) {
487
+ t .Errorf ("expected %x, got %x\n " , exp , doubleFixedArrStrPack )
488
+ }
489
+
490
+ // test string, fixed array uint256[2], dynamic array uint256[], fixed array uint256[3]
491
+ strin = "hello world"
492
+ fixedarrin1 = [2 ]* big.Int {big .NewInt (1 ), big .NewInt (2 )}
493
+ dynarrin = []* big.Int {big .NewInt (1 ), big .NewInt (2 )}
494
+ fixedarrin2 = [3 ]* big.Int {big .NewInt (1 ), big .NewInt (2 ), big .NewInt (3 )}
495
+ multipleMixedArrStrPack , err := abi .Pack ("multipleMixedArrStr" , strin , fixedarrin1 , dynarrin , fixedarrin2 )
496
+ if err != nil {
497
+ t .Error (err )
498
+ }
499
+
500
+ // generate expected output
501
+ stroffset = make ([]byte , 32 )
502
+ stroffset [31 ] = 224
503
+ strlength = make ([]byte , 32 )
504
+ strlength [31 ] = byte (len (strin ))
505
+ strvalue = common .RightPadBytes ([]byte (strin ), 32 )
506
+ fixedarrin1value1 = common .LeftPadBytes (fixedarrin1 [0 ].Bytes (), 32 )
507
+ fixedarrin1value2 = common .LeftPadBytes (fixedarrin1 [1 ].Bytes (), 32 )
508
+ dynarroffset = U256 (big .NewInt (int64 (256 + ((len (strin )/ 32 )+ 1 )* 32 )))
509
+ dynarrlength = make ([]byte , 32 )
510
+ dynarrlength [31 ] = byte (len (dynarrin ))
511
+ dynarrinvalue1 = common .LeftPadBytes (dynarrin [0 ].Bytes (), 32 )
512
+ dynarrinvalue2 = common .LeftPadBytes (dynarrin [1 ].Bytes (), 32 )
513
+ fixedarrin2value1 = common .LeftPadBytes (fixedarrin2 [0 ].Bytes (), 32 )
514
+ fixedarrin2value2 = common .LeftPadBytes (fixedarrin2 [1 ].Bytes (), 32 )
515
+ fixedarrin2value3 = common .LeftPadBytes (fixedarrin2 [2 ].Bytes (), 32 )
516
+ exp = append (stroffset , fixedarrin1value1 ... )
517
+ exp = append (exp , fixedarrin1value2 ... )
518
+ exp = append (exp , dynarroffset ... )
519
+ exp = append (exp , fixedarrin2value1 ... )
520
+ exp = append (exp , fixedarrin2value2 ... )
521
+ exp = append (exp , fixedarrin2value3 ... )
522
+ exp = append (exp , append (strlength , strvalue ... )... )
523
+ dynarrarg = append (dynarrlength , dynarrinvalue1 ... )
524
+ dynarrarg = append (dynarrarg , dynarrinvalue2 ... )
525
+ exp = append (exp , dynarrarg ... )
526
+
527
+ // ignore first 4 bytes of the output. This is the function identifier
528
+ multipleMixedArrStrPack = multipleMixedArrStrPack [4 :]
529
+ if ! bytes .Equal (multipleMixedArrStrPack , exp ) {
530
+ t .Errorf ("expected %x, got %x\n " , exp , multipleMixedArrStrPack )
531
+ }
532
+ }
533
+
352
534
func TestDefaultFunctionParsing (t * testing.T ) {
353
535
const definition = `[{ "name" : "balance" }]`
354
536
0 commit comments