@@ -441,10 +441,35 @@ public static byte[] GenerateScript(UInt160 scriptHash, object[] args, bool addN
441
441
public void GenerateInputsOutputs ( KeyPair key , string symbol , IEnumerable < Transaction . Output > targets , out List < Transaction . Input > inputs , out List < Transaction . Output > outputs , decimal system_fee = 0 )
442
442
{
443
443
var from_script_hash = new UInt160 ( key . signatureHash . ToArray ( ) ) ;
444
- GenerateInputsOutputs ( from_script_hash , symbol , targets , out inputs , out outputs , system_fee ) ;
444
+ var info = GetAssetsInfo ( ) ;
445
+ var targetAssetID = LuxUtils . ReverseHex ( info [ symbol ] ) . HexToBytes ( ) ;
446
+ if ( targets != null )
447
+ foreach ( var t in targets )
448
+ if ( t . assetID == null )
449
+ t . assetID = targetAssetID ;
450
+ //else Console.WriteLine("ASSETID target already existed: " + symbol);
451
+ GenerateInputsOutputs ( from_script_hash , targets , out inputs , out outputs , system_fee ) ;
445
452
}
446
453
447
- public void GenerateInputsOutputs ( UInt160 from_script_hash , string symbol , IEnumerable < Transaction . Output > targets , out List < Transaction . Input > inputs , out List < Transaction . Output > outputs , decimal system_fee = 0 )
454
+ public void GenerateInputsOutputs ( UInt160 key , string symbol , IEnumerable < Transaction . Output > targets , out List < Transaction . Input > inputs , out List < Transaction . Output > outputs , decimal system_fee = 0 )
455
+ {
456
+ var info = GetAssetsInfo ( ) ;
457
+ var targetAssetID = LuxUtils . ReverseHex ( info [ symbol ] ) . HexToBytes ( ) ;
458
+ if ( targets != null )
459
+ foreach ( var t in targets )
460
+ if ( t . assetID == null )
461
+ t . assetID = targetAssetID ;
462
+ // else Console.WriteLine("ASSETID target already existed: " + symbol);
463
+ GenerateInputsOutputs ( key , symbol , targets , out inputs , out outputs , system_fee ) ;
464
+ }
465
+
466
+ public void GenerateInputsOutputs ( KeyPair key , IEnumerable < Transaction . Output > targets , out List < Transaction . Input > inputs , out List < Transaction . Output > outputs , decimal system_fee = 0 )
467
+ {
468
+ var from_script_hash = new UInt160 ( key . signatureHash . ToArray ( ) ) ;
469
+ GenerateInputsOutputs ( from_script_hash , targets , out inputs , out outputs , system_fee ) ;
470
+ }
471
+
472
+ public void GenerateInputsOutputs ( UInt160 from_script_hash , IEnumerable < Transaction . Output > targets , out List < Transaction . Input > inputs , out List < Transaction . Output > outputs , decimal system_fee = 0 )
448
473
{
449
474
var unspent = GetUnspent ( from_script_hash ) ;
450
475
// filter any asset lists with zero unspent inputs
@@ -453,123 +478,166 @@ public void GenerateInputsOutputs(UInt160 from_script_hash, string symbol, IEnum
453
478
inputs = new List < Transaction . Input > ( ) ;
454
479
outputs = new List < Transaction . Output > ( ) ;
455
480
456
- string assetID ;
457
-
458
- var info = GetAssetsInfo ( ) ;
459
- if ( info . ContainsKey ( symbol ) )
460
- {
461
- assetID = info [ symbol ] ;
462
- }
463
- else
464
- {
465
- throw new NeoException ( $ "{ symbol } is not a valid blockchain asset.") ;
466
- }
467
-
468
481
var from_address = from_script_hash . ToAddress ( ) ;
482
+ var info = GetAssetsInfo ( ) ;
469
483
470
- if ( ! unspent . ContainsKey ( symbol ) )
484
+ // dummy tx to self
485
+ if ( targets == null )
471
486
{
472
- throw new NeoException ( $ "Not enough { symbol } in address { from_address } ") ;
473
- }
487
+ string assetName = "GAS" ;
488
+ string assetID = info [ assetName ] ;
489
+ var targetAssetID = LuxUtils . ReverseHex ( assetID ) . HexToBytes ( ) ;
490
+ if ( ! unspent . ContainsKey ( assetName ) )
491
+ throw new NeoException ( $ "Not enough { assetName } in address { from_address } ") ;
474
492
475
- decimal cost = 0 ;
493
+ var src = unspent [ assetName ] [ 0 ] ;
494
+ decimal selected = src . value ;
495
+ // Console.WriteLine("SENDING " + selected + " GAS to source");
476
496
477
- if ( targets != null )
478
- {
479
- foreach ( var target in targets )
497
+ inputs . Add ( new Transaction . Input ( )
480
498
{
481
- if ( target . scriptHash . Equals ( from_script_hash ) )
482
- {
483
- throw new NeoException ( "Target can't be same as input" ) ;
484
- }
499
+ prevHash = src . hash ,
500
+ prevIndex = src . index ,
501
+ } ) ;
485
502
486
- cost += target . value ;
487
- }
503
+ outputs . Add ( new Transaction . Output ( )
504
+ {
505
+ assetID = targetAssetID ,
506
+ scriptHash = from_script_hash ,
507
+ value = selected
508
+ } ) ;
509
+ return ;
488
510
}
489
511
490
- var targetAssetID = LuxUtils . ReverseHex ( assetID ) . HexToBytes ( ) ;
512
+ foreach ( var target in targets )
513
+ if ( target . scriptHash . Equals ( from_script_hash ) )
514
+ throw new NeoException ( "Target can't be same as input" ) ;
491
515
492
- var sources = unspent [ symbol ] ;
493
- decimal selected = 0 ;
494
-
495
- if ( lastTransactions . ContainsKey ( from_address ) )
516
+ bool done_fee = false ;
517
+ foreach ( var asset in info )
496
518
{
497
- var lastTx = lastTransactions [ from_address ] ;
498
-
499
- uint index = 0 ;
500
- if ( lastTx . outputs != null )
501
- {
502
- foreach ( var output in lastTx . outputs )
503
- {
504
- if ( output . assetID . SequenceEqual ( targetAssetID ) && output . scriptHash . Equals ( from_script_hash ) )
505
- {
506
- selected += output . value ;
519
+ string assetName = asset . Key ;
520
+ string assetID = asset . Value ;
507
521
508
- var input = new Transaction . Input ( )
509
- {
510
- prevHash = lastTx . Hash ,
511
- prevIndex = index ,
512
- } ;
522
+ if ( ! unspent . ContainsKey ( assetName ) )
523
+ continue ;
513
524
514
- inputs . Add ( input ) ;
525
+ var targetAssetID = LuxUtils . ReverseHex ( assetID ) . HexToBytes ( ) ;
515
526
516
- break ;
517
- }
527
+ var thistargets = targets . Where ( o => o . assetID . SequenceEqual ( targetAssetID ) ) ;
518
528
519
- index ++ ;
529
+ decimal cost = - 1 ;
530
+ foreach ( var target in thistargets )
531
+ if ( target . assetID . SequenceEqual ( targetAssetID ) )
532
+ {
533
+ if ( cost < 0 )
534
+ cost = 0 ;
535
+ cost += target . value ;
520
536
}
521
- }
522
- }
523
537
524
- foreach ( var src in sources )
525
- {
526
- if ( selected >= cost && inputs . Count > 0 )
538
+ // incorporate fee in GAS utxo, if sending GAS
539
+ bool sendfee = false ;
540
+ if ( system_fee > 0 && assetName == "GAS" )
527
541
{
528
- break ;
542
+ done_fee = true ;
543
+ sendfee = true ;
544
+ if ( cost < 0 )
545
+ cost = 0 ;
546
+ cost += system_fee ;
529
547
}
530
548
531
- selected += src . value ;
549
+ if ( cost == - 1 )
550
+ continue ;
551
+
552
+ var sources = unspent [ assetName ] . OrderBy ( src => src . value ) ;
553
+ decimal selected = 0 ;
532
554
533
- var input = new Transaction . Input ( )
555
+ // >= cost ou > cost??
556
+ foreach ( var src in sources )
534
557
{
535
- prevHash = src . hash ,
536
- prevIndex = src . index ,
537
- } ;
558
+ if ( selected >= cost && inputs . Count > 0 )
559
+ break ;
538
560
539
- inputs . Add ( input ) ;
540
- }
561
+ selected += src . value ;
562
+ inputs . Add ( new Transaction . Input ( )
563
+ {
564
+ prevHash = src . hash ,
565
+ prevIndex = src . index ,
566
+ } ) ;
567
+ // Console.WriteLine("ADD inp " + src.ToString());
568
+ }
541
569
542
- if ( selected < cost )
543
- {
544
- throw new NeoException ( $ "Not enough { symbol } ") ;
545
- }
570
+ if ( selected < cost )
571
+ throw new NeoException ( $ "Not enough { assetName } in address { from_address } ") ;
546
572
547
- if ( cost > 0 && targets != null )
548
- {
549
- foreach ( var target in targets )
550
- {
551
- var output = new Transaction . Output ( )
573
+ if ( cost > 0 )
574
+ foreach ( var target in thistargets )
575
+ outputs . Add ( target ) ;
576
+
577
+ if ( selected > cost || cost == 0 || sendfee ) /// is sendfee needed? yes if selected == cost
578
+ outputs . Add ( new Transaction . Output ( )
552
579
{
553
580
assetID = targetAssetID ,
554
- scriptHash = target . scriptHash ,
555
- value = target . value
556
- } ;
557
- outputs . Add ( output ) ;
558
- }
581
+ scriptHash = from_script_hash ,
582
+ value = selected - cost
583
+ } ) ;
559
584
}
585
+ /*
586
+ if (system_fee > 0 && !done_fee && false)
587
+ {
588
+ var gasID = LuxUtils.ReverseHex(info["GAS"]).HexToBytes();
589
+ var gassources = unspent["GAS"];
590
+ // foreach (var src in gassources)
591
+ // Console.WriteLine("SRC: " + src.ToString());
592
+ decimal feeselected = 0;
593
+ foreach (var src in gassources)
594
+ if (feeselected <= system_fee)
595
+ {
596
+ inputs.Add(new Transaction.Input()
597
+ {
598
+ prevHash = src.hash,
599
+ prevIndex = src.index,
600
+ });
601
+ feeselected += src.value;
602
+ Console.WriteLine("add input " + feeselected);
603
+ break;
604
+ }
605
+ outputs.Add(new Transaction.Output()
606
+ {
607
+ assetID = gasID,
608
+ scriptHash = from_script_hash,
609
+ value = feeselected - system_fee
610
+ });
611
+ }
560
612
561
- if ( selected > cost || cost == 0 )
562
- {
563
- var left = selected - cost ;
613
+ foreach (var i in inputs)
614
+ Console.WriteLine("INPUT " + i);
615
+ foreach (var i in output)
616
+ Console.WriteLine("OUTPUT " + i);
617
+ // chaining
618
+ if (lastTransactions.ContainsKey(from_address))
619
+ {
620
+ var lastTx = lastTransactions[from_address];
621
+ uint index = 0;
622
+ if (lastTx.outputs != null)
623
+ foreach (var output in lastTx.outputs)
624
+ {
625
+ if (output.assetID.SequenceEqual(targetAssetID) && output.scriptHash.Equals(from_script_hash))
626
+ {
627
+ selected += output.value;
628
+ var input = new Transaction.Input()
629
+ {
630
+ prevHash = lastTx.Hash,
631
+ prevIndex = index,
632
+ };
633
+ inputs.Add(input);
634
+ break;
635
+ }
636
+ index++;
637
+ }
638
+ }
639
+ */
564
640
565
- var change = new Transaction . Output ( )
566
- {
567
- assetID = targetAssetID ,
568
- scriptHash = from_script_hash ,
569
- value = left
570
- } ;
571
- outputs . Add ( change ) ;
572
- }
573
641
}
574
642
575
643
public Transaction CallContract ( KeyPair key , UInt160 scriptHash , object [ ] args , string attachSymbol = null , IEnumerable < Transaction . Output > attachTargets = null )
0 commit comments