github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/validation/test/tx_ugly_test.go (about)

     1  package test
     2  
     3  import (
     4  	"encoding/hex"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/bytom/bytom/account"
     9  	"github.com/bytom/bytom/blockchain/signers"
    10  	"github.com/bytom/bytom/consensus"
    11  	"github.com/bytom/bytom/crypto/ed25519/chainkd"
    12  	"github.com/bytom/bytom/protocol/bc"
    13  	"github.com/bytom/bytom/protocol/bc/types"
    14  	"github.com/bytom/bytom/protocol/validation"
    15  	"github.com/bytom/bytom/protocol/vm/vmutil"
    16  	"github.com/bytom/bytom/testutil"
    17  )
    18  
    19  func TestValidateUglyTx(t *testing.T) {
    20  	singleSignInst := &signingInst{
    21  		rootPrvKeys: []string{
    22  			"38d2c44314c401b3ea7c23c54e12c36a527aee46a7f26b82443a46bf40583e439dea25de09b0018b35a741d8cd9f6ec06bc11db49762617485f5309ab72a12d4",
    23  		},
    24  		quorum:           1,
    25  		keyIndex:         1,
    26  		ctrlProgramIndex: 1,
    27  		change:           false,
    28  	}
    29  	multiSignInst := &signingInst{
    30  		rootPrvKeys: []string{
    31  			"a080aca2d9d7948d005c92d0729c618e56fb5551a52dfa04dc4caaf3c8b8a94c89a9795f5bbfd2b885ce7a9d3e3efa5386436c3681b21f9263a0b0a544346b48",
    32  			"105295324626e33bb7d8e8a57c6a0aa495346d7fc342a4891ece00424494cf48f75cefa0f8c61674a12238cfa711b4bc26cb22f38b6e2206c691b83943a58312",
    33  			"c02bb73d1aee56f8935fb7704f71f668eb37ec223baf5723b38a186669b465427d1bdbc2c4397c1259d12b6229aaf6154aaccdeb8addce3a780a1cbc1025ad25",
    34  			"a0c2225685e4c4439f12c264d1573db063ddbc929d4b8a3e1641e8abb4df504a56b1200b9925138d79febe6e1156fcfaf0d1878f25cbccc5db4c8fea55bde198",
    35  			"20d06d4fd261ab554e01104f019392f89566acace727e6bb6de4544aa3a6b248480232155332e6e5de10a62e4a9a4c1d9e3b7f9cb4fd196142ef1d080b8bbaec",
    36  		},
    37  		quorum:           3,
    38  		keyIndex:         1,
    39  		ctrlProgramIndex: 1,
    40  		change:           false,
    41  	}
    42  	cases := []struct {
    43  		category string
    44  		desc     string
    45  		insts    []*signingInst
    46  		txData   types.TxData
    47  		err      bool
    48  	}{
    49  		{
    50  			category: "fee insufficient",
    51  			desc:     "sum of btm output greater than btm input",
    52  			insts:    []*signingInst{singleSignInst},
    53  			txData: types.TxData{
    54  				Version: 1,
    55  				Inputs: []*types.TxInput{
    56  					types.NewSpendInput(nil,
    57  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
    58  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
    59  				},
    60  				Outputs: []*types.TxOutput{
    61  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 10000000001, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
    62  				},
    63  			},
    64  			err:      true,
    65  		},
    66  		{
    67  			category: "fee insufficient",
    68  			desc:     "sum of btm output equals to input btm",
    69  			insts:    []*signingInst{singleSignInst},
    70  			txData: types.TxData{
    71  				Version: 1,
    72  				Inputs: []*types.TxInput{
    73  					types.NewSpendInput(nil,
    74  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
    75  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
    76  				},
    77  				Outputs: []*types.TxOutput{
    78  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
    79  				},
    80  			},
    81  			err:      true,
    82  		},
    83  		{
    84  			category: "fee insufficient",
    85  			desc:     "sum of btm input greater than btm output, but still insufficient",
    86  			insts:    []*signingInst{singleSignInst},
    87  			txData: types.TxData{
    88  				Version: 1,
    89  				Inputs: []*types.TxInput{
    90  					types.NewSpendInput(nil,
    91  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
    92  						*consensus.BTMAssetID, 10000000001, 0, nil, nil),
    93  				},
    94  				Outputs: []*types.TxOutput{
    95  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
    96  				},
    97  			},
    98  			err:      true,
    99  		},
   100  		{
   101  			category: "fee insufficient",
   102  			desc:     "no btm input",
   103  			insts:    []*signingInst{singleSignInst},
   104  			txData: types.TxData{
   105  				Version: 1,
   106  				Inputs: []*types.TxInput{
   107  					types.NewSpendInput(nil,
   108  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   109  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, nil, nil),
   110  				},
   111  				Outputs: []*types.TxOutput{
   112  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   113  				},
   114  			},
   115  			err:      true,
   116  		},
   117  		{
   118  			category: "input output unbalance",
   119  			desc:     "only has btm input, no output",
   120  			insts:    []*signingInst{singleSignInst},
   121  			txData: types.TxData{
   122  				Version: 1,
   123  				Inputs: []*types.TxInput{
   124  					types.NewSpendInput(nil,
   125  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   126  						*consensus.BTMAssetID, 10000000001, 0, nil, nil),
   127  				},
   128  				Outputs: []*types.TxOutput{},
   129  			},
   130  			err:      true,
   131  		},
   132  		{
   133  			category: "input output unbalance",
   134  			desc:     "issuance asset, no corresponding output",
   135  			insts:    []*signingInst{singleSignInst, singleSignInst},
   136  			txData: types.TxData{
   137  				Version: 1,
   138  				Inputs: []*types.TxInput{
   139  					types.NewSpendInput(nil,
   140  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   141  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   142  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   143  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   144  						10000000000,
   145  						nil,
   146  						nil,
   147  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   148  					),
   149  				},
   150  				Outputs: []*types.TxOutput{
   151  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   152  				},
   153  			},
   154  			err:      true,
   155  		},
   156  		{
   157  			category: "input output unbalance",
   158  			desc:     "issuance asset A, output asset B",
   159  			insts:    []*signingInst{singleSignInst, singleSignInst},
   160  			txData: types.TxData{
   161  				Version: 1,
   162  				Inputs: []*types.TxInput{
   163  					types.NewSpendInput(nil,
   164  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   165  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   166  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   167  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   168  						10000000000,
   169  						nil,
   170  						nil,
   171  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   172  					),
   173  				},
   174  				Outputs: []*types.TxOutput{
   175  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   176  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707e"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   177  				},
   178  			},
   179  			err:      true,
   180  		},
   181  		{
   182  			category: "input output unbalance",
   183  			desc:     "sum of output asset A greater than issuance asset A",
   184  			insts:    []*signingInst{singleSignInst, singleSignInst},
   185  			txData: types.TxData{
   186  				Version: 1,
   187  				Inputs: []*types.TxInput{
   188  					types.NewSpendInput(nil,
   189  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   190  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   191  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   192  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   193  						10000000000,
   194  						nil,
   195  						nil,
   196  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   197  					),
   198  				},
   199  				Outputs: []*types.TxOutput{
   200  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   201  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   202  				},
   203  			},
   204  			err:      true,
   205  		},
   206  		{
   207  			category: "input output unbalance",
   208  			desc:     "sum of output asset A less than issuance asset A",
   209  			insts:    []*signingInst{singleSignInst, singleSignInst},
   210  			txData: types.TxData{
   211  				Version: 1,
   212  				Inputs: []*types.TxInput{
   213  					types.NewSpendInput(nil,
   214  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   215  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   216  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   217  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   218  						10000000000,
   219  						nil,
   220  						nil,
   221  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   222  					),
   223  				},
   224  				Outputs: []*types.TxOutput{
   225  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   226  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   227  				},
   228  			},
   229  			err:      true,
   230  		},
   231  		{
   232  			category: "input output unbalance",
   233  			desc:     "sum of retire asset A greater than issuance asset A",
   234  			insts:    []*signingInst{singleSignInst, singleSignInst},
   235  			txData: types.TxData{
   236  				Version: 1,
   237  				Inputs: []*types.TxInput{
   238  					types.NewSpendInput(nil,
   239  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   240  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   241  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   242  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   243  						10000000000,
   244  						nil,
   245  						nil,
   246  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   247  					),
   248  				},
   249  				Outputs: []*types.TxOutput{
   250  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   251  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("6a"), nil),
   252  				},
   253  			},
   254  			err:      true,
   255  		},
   256  		{
   257  			category: "input output unbalance",
   258  			desc:     "sum of retire asset A less than issuance asset A",
   259  			insts:    []*signingInst{singleSignInst, singleSignInst},
   260  			txData: types.TxData{
   261  				Version: 1,
   262  				Inputs: []*types.TxInput{
   263  					types.NewSpendInput(nil,
   264  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   265  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   266  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   267  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   268  						10000000000,
   269  						nil,
   270  						nil,
   271  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   272  					),
   273  				},
   274  				Outputs: []*types.TxOutput{
   275  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   276  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("6a"), nil),
   277  				},
   278  			},
   279  			err:      true,
   280  		},
   281  		{
   282  			category: "input output unbalance",
   283  			desc:     "spend asset A, no corresponding output",
   284  			insts:    []*signingInst{singleSignInst, singleSignInst},
   285  			txData: types.TxData{
   286  				Version: 1,
   287  				Inputs: []*types.TxInput{
   288  					types.NewSpendInput(nil,
   289  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   290  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   291  					types.NewSpendInput(nil,
   292  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   293  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   294  				},
   295  				Outputs: []*types.TxOutput{
   296  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   297  				},
   298  			},
   299  			err:      true,
   300  		},
   301  		{
   302  			category: "input output unbalance",
   303  			desc:     "spend asset A, output asset B",
   304  			insts:    []*signingInst{singleSignInst, singleSignInst},
   305  			txData: types.TxData{
   306  				Version: 1,
   307  				Inputs: []*types.TxInput{
   308  					types.NewSpendInput(nil,
   309  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   310  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   311  					types.NewSpendInput(nil,
   312  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   313  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   314  				},
   315  				Outputs: []*types.TxOutput{
   316  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   317  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707e"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   318  				},
   319  			},
   320  			err:      true,
   321  		},
   322  		{
   323  			category: "input output unbalance",
   324  			desc:     "sum of output asset A greater than spend asset A",
   325  			insts:    []*signingInst{singleSignInst, singleSignInst},
   326  			txData: types.TxData{
   327  				Version: 1,
   328  				Inputs: []*types.TxInput{
   329  					types.NewSpendInput(nil,
   330  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   331  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   332  					types.NewSpendInput(nil,
   333  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   334  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   335  				},
   336  				Outputs: []*types.TxOutput{
   337  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   338  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   339  				},
   340  			},
   341  			err:      true,
   342  		},
   343  		{
   344  			category: "input output unbalance",
   345  			desc:     "sum of output asset A less than spend asset A",
   346  			insts:    []*signingInst{singleSignInst, singleSignInst},
   347  			txData: types.TxData{
   348  				Version: 1,
   349  				Inputs: []*types.TxInput{
   350  					types.NewSpendInput(nil,
   351  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   352  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   353  					types.NewSpendInput(nil,
   354  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   355  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   356  				},
   357  				Outputs: []*types.TxOutput{
   358  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   359  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   360  				},
   361  			},
   362  			err:      true,
   363  		},
   364  		{
   365  			category: "input output unbalance",
   366  			desc:     "sum of retire asset A greater than spend asset A",
   367  			insts:    []*signingInst{singleSignInst, singleSignInst},
   368  			txData: types.TxData{
   369  				Version: 1,
   370  				Inputs: []*types.TxInput{
   371  					types.NewSpendInput(nil,
   372  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   373  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   374  					types.NewSpendInput(nil,
   375  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   376  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   377  				},
   378  				Outputs: []*types.TxOutput{
   379  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   380  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("6a"), nil),
   381  				},
   382  			},
   383  			err:      true,
   384  		},
   385  		{
   386  			category: "input output unbalance",
   387  			desc:     "sum of retire asset A less than spend asset A",
   388  			insts:    []*signingInst{singleSignInst, singleSignInst},
   389  			txData: types.TxData{
   390  				Version: 1,
   391  				Inputs: []*types.TxInput{
   392  					types.NewSpendInput(nil,
   393  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   394  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   395  					types.NewSpendInput(nil,
   396  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   397  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   398  				},
   399  				Outputs: []*types.TxOutput{
   400  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   401  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 5000000000, testutil.MustDecodeHexString("6a"), nil),
   402  				},
   403  			},
   404  			err:      true,
   405  		},
   406  		{
   407  			category: "input output unbalance",
   408  			desc:     "use retired utxo",
   409  			insts:    []*signingInst{singleSignInst, singleSignInst},
   410  			txData: types.TxData{
   411  				Version: 1,
   412  				Inputs: []*types.TxInput{
   413  					types.NewSpendInput(nil,
   414  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   415  						*consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("6a"), nil),
   416  				},
   417  				Outputs: []*types.TxOutput{
   418  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   419  				},
   420  			},
   421  			err:      true,
   422  		},
   423  		{
   424  			category: "input output unbalance",
   425  			desc:     "input utxo is zero",
   426  			insts:    []*signingInst{singleSignInst},
   427  			txData: types.TxData{
   428  				Version: 1,
   429  				Inputs: []*types.TxInput{
   430  					types.NewSpendInput(nil,
   431  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   432  						*consensus.BTMAssetID, 0, 0, nil, nil),
   433  				},
   434  				Outputs: []*types.TxOutput{
   435  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 0, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   436  				},
   437  			},
   438  			err:      true,
   439  		},
   440  		{
   441  			category: "input output unbalance",
   442  			desc:     "no btm input",
   443  			txData: types.TxData{
   444  				Version: 1,
   445  				Inputs:  []*types.TxInput{},
   446  				Outputs: []*types.TxOutput{
   447  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 10, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   448  				},
   449  			},
   450  			err:      true,
   451  		},
   452  		{
   453  			category: "overflow",
   454  			desc:     "spend btm input overflow",
   455  			insts:    []*signingInst{singleSignInst, singleSignInst},
   456  			txData: types.TxData{
   457  				Version: 1,
   458  				Inputs: []*types.TxInput{
   459  					types.NewSpendInput(nil,
   460  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   461  						*consensus.BTMAssetID, math.MaxUint64, 0, nil, nil),
   462  					types.NewSpendInput(nil,
   463  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   464  						*consensus.BTMAssetID, 10000000000, 1, nil, nil),
   465  				},
   466  				Outputs: []*types.TxOutput{
   467  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   468  				},
   469  			},
   470  			err:      true,
   471  		},
   472  		{
   473  			category: "overflow",
   474  			desc:     "spend non btm input overflow",
   475  			insts:    []*signingInst{singleSignInst, singleSignInst, singleSignInst},
   476  			txData: types.TxData{
   477  				Version: 1,
   478  				Inputs: []*types.TxInput{
   479  					types.NewSpendInput(nil,
   480  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   481  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), math.MaxInt64, 0, nil, nil),
   482  					types.NewSpendInput(nil,
   483  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   484  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, 0, nil, nil),
   485  					types.NewSpendInput(nil,
   486  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   487  						*consensus.BTMAssetID, 10000000000, 1, nil, nil),
   488  				},
   489  				Outputs: []*types.TxOutput{
   490  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   491  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   492  				},
   493  			},
   494  			err:      true,
   495  		},
   496  		{
   497  			category: "overflow",
   498  			desc:     "issuance non btm input overflow",
   499  			insts:    []*signingInst{singleSignInst, singleSignInst, singleSignInst},
   500  			txData: types.TxData{
   501  				Version: 1,
   502  				Inputs: []*types.TxInput{
   503  					types.NewSpendInput(nil,
   504  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   505  						*consensus.BTMAssetID, 10000000000, 1, nil, nil),
   506  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   507  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   508  						math.MaxInt64,
   509  						nil,
   510  						[][]byte{
   511  							testutil.MustDecodeHexString("e8f301f7bd3b1e4ca853b15559b3a253a4f5f9c7efba233ab0f6896bec23adc6a816c350e08f6b8ac5bc23eb5720173f9190805328af581f34a7fe561358d100"),
   512  						},
   513  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   514  					),
   515  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   516  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   517  						10000000000,
   518  						nil,
   519  						nil,
   520  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   521  					),
   522  				},
   523  				Outputs: []*types.TxOutput{
   524  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   525  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   526  				},
   527  			},
   528  			err:      true,
   529  		},
   530  		{
   531  			category: "overflow",
   532  			desc:     "sum of spend and issuance non btm input overflow",
   533  			insts:    []*signingInst{singleSignInst, singleSignInst, singleSignInst},
   534  			txData: types.TxData{
   535  				Version: 1,
   536  				Inputs: []*types.TxInput{
   537  					types.NewSpendInput(nil,
   538  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   539  						*consensus.BTMAssetID, 10000000000, 1, nil, nil),
   540  					types.NewIssuanceInput( // assetID: 97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f
   541  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   542  						math.MaxInt64,
   543  						nil,
   544  						nil,
   545  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   546  					),
   547  					types.NewSpendInput(nil,
   548  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   549  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, 0, nil, nil),
   550  				},
   551  				Outputs: []*types.TxOutput{
   552  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   553  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 100, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   554  				},
   555  			},
   556  			err:      true,
   557  		},
   558  		{
   559  			category: "overflow",
   560  			desc:     "spend btm output overflow",
   561  			insts:    []*signingInst{singleSignInst, singleSignInst},
   562  			txData: types.TxData{
   563  				Version: 1,
   564  				Inputs: []*types.TxInput{
   565  					types.NewSpendInput(nil,
   566  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   567  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   568  				},
   569  				Outputs: []*types.TxOutput{
   570  					types.NewOriginalTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   571  				},
   572  			},
   573  			err:      true,
   574  		},
   575  		{
   576  			category: "overflow",
   577  			desc:     "retire btm output overflow",
   578  			insts:    []*signingInst{singleSignInst, singleSignInst},
   579  			txData: types.TxData{
   580  				Version: 1,
   581  				Inputs: []*types.TxInput{
   582  					types.NewSpendInput(nil,
   583  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   584  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   585  				},
   586  				Outputs: []*types.TxOutput{
   587  					types.NewOriginalTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("6a"), nil),
   588  				},
   589  			},
   590  			err:      true,
   591  		},
   592  		{
   593  			category: "overflow",
   594  			desc:     "non btm output overflow",
   595  			insts:    []*signingInst{singleSignInst, singleSignInst},
   596  			txData: types.TxData{
   597  				Version: 1,
   598  				Inputs: []*types.TxInput{
   599  					types.NewSpendInput(nil,
   600  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   601  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   602  					types.NewSpendInput(nil,
   603  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   604  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   605  				},
   606  				Outputs: []*types.TxOutput{
   607  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   608  					types.NewOriginalTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   609  				},
   610  			},
   611  			err:      true,
   612  		},
   613  		{
   614  			category: "overflow",
   615  			desc:     "retire non btm output overflow",
   616  			insts:    []*signingInst{singleSignInst, singleSignInst},
   617  			txData: types.TxData{
   618  				Version: 1,
   619  				Inputs: []*types.TxInput{
   620  					types.NewSpendInput(nil,
   621  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   622  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   623  					types.NewSpendInput(nil,
   624  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   625  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, nil, nil),
   626  				},
   627  				Outputs: []*types.TxOutput{
   628  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   629  					types.NewOriginalTxOutput(*consensus.BTMAssetID, math.MaxUint64, testutil.MustDecodeHexString("6a"), nil),
   630  				},
   631  			},
   632  			err:      true,
   633  		},
   634  		{
   635  			category: "overflow",
   636  			desc:     "output with over range amount but sum in equal",
   637  			insts:    []*signingInst{singleSignInst, singleSignInst},
   638  			txData: types.TxData{
   639  				Version: 1,
   640  				Inputs: []*types.TxInput{
   641  					types.NewSpendInput(nil,
   642  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   643  						*consensus.BTMAssetID, 100000000, 0, nil, nil),
   644  				},
   645  				Outputs: []*types.TxOutput{
   646  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 18446744073609551616, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   647  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 18446744073609551616, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   648  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 290000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   649  				},
   650  			},
   651  			err:      true,
   652  		},
   653  		{
   654  			category: "verify signature fail",
   655  			desc:     "btm single sign",
   656  			insts:    []*signingInst{singleSignInst},
   657  			txData: types.TxData{
   658  				Version: 1,
   659  				Inputs: []*types.TxInput{
   660  					types.NewSpendInput(nil,
   661  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   662  						*consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("00140876db6ca8f4542a836f0edd42b87d095d081182"), nil), // wrong control program
   663  				},
   664  				Outputs: []*types.TxOutput{
   665  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   666  				},
   667  			},
   668  			err:      true,
   669  		},
   670  		{
   671  			category: "verify signature fail",
   672  			desc:     "btm multi sign",
   673  			insts:    []*signingInst{multiSignInst},
   674  			txData: types.TxData{
   675  				Version: 1,
   676  				Inputs: []*types.TxInput{
   677  					types.NewSpendInput(nil,
   678  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   679  						*consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("00200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac66"), nil), // wrong control program
   680  				},
   681  				Outputs: []*types.TxOutput{
   682  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   683  				},
   684  			},
   685  			err:      true,
   686  		},
   687  		{
   688  			category: "verify signature fail",
   689  			desc:     "spend non btm single sign",
   690  			insts:    []*signingInst{singleSignInst, singleSignInst},
   691  			txData: types.TxData{
   692  				Version: 1,
   693  				Inputs: []*types.TxInput{
   694  					types.NewSpendInput(nil,
   695  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   696  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   697  					types.NewSpendInput(nil,
   698  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   699  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, testutil.MustDecodeHexString("00140876db6ca8f4542a836f0edd42b87d095d081182"), nil), // wrong control program
   700  				},
   701  				Outputs: []*types.TxOutput{
   702  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   703  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   704  				},
   705  			},
   706  			err:      true,
   707  		},
   708  		{
   709  			category: "verify signature fail",
   710  			desc:     "spend non btm multi sign",
   711  			insts:    []*signingInst{singleSignInst, multiSignInst},
   712  			txData: types.TxData{
   713  				Version: 1,
   714  				Inputs: []*types.TxInput{
   715  					types.NewSpendInput(nil,
   716  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   717  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   718  					types.NewSpendInput(nil,
   719  						bc.Hash{V0: 6970879411704044573, V1: 10086395903308657573, V2: 10107608596190358115, V3: 8645856247221333302},
   720  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 1, testutil.MustDecodeHexString("00140876db6ca8f4542a836f0edd42b87d095d081182"), nil), // wrong control program
   721  				},
   722  				Outputs: []*types.TxOutput{
   723  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   724  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   725  				},
   726  			},
   727  			err:      true,
   728  		},
   729  		{
   730  			category: "verify signature fail",
   731  			desc:     "issuance non btm single sign",
   732  			insts:    []*signingInst{singleSignInst, multiSignInst},
   733  			txData: types.TxData{
   734  				Version: 1,
   735  				Inputs: []*types.TxInput{
   736  					types.NewSpendInput(nil,
   737  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   738  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   739  					types.NewIssuanceInput(
   740  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   741  						10000000000,
   742  						// wrong issuance program
   743  						testutil.MustDecodeHexString("ae20c38173d800e62f63bd08cfaa9bc905e4a34a61ad841d7ad6c70ead0fb48196995151ad"),
   744  						nil,
   745  						nil,
   746  					),
   747  				},
   748  				Outputs: []*types.TxOutput{
   749  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   750  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("bf5f8da2334590ee095148ccdcf4d806b26a47a6d9e9e857ef6c2de79aee4f14"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   751  				},
   752  			},
   753  			err:      true,
   754  		},
   755  		{
   756  			category: "verify signature fail",
   757  			desc:     "issuance non btm multi sign",
   758  			insts:    []*signingInst{singleSignInst, multiSignInst},
   759  			txData: types.TxData{
   760  				Version: 1,
   761  				Inputs: []*types.TxInput{
   762  					types.NewSpendInput(nil,
   763  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   764  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   765  					types.NewIssuanceInput(
   766  						testutil.MustDecodeHexString("fd0aec4229deb281"),
   767  						10000000000,
   768  						// wrong issuance program
   769  						testutil.MustDecodeHexString("ae20ce8639c5dc70cb2b12f89a057670602eb013fc54a10ce22bd4691c62cf546b7b2081bdd879bcbce7f58e1731841c6b3deac242efa00e75124fe559fa531c0c5bb820b40b6eec74288ee4bae67191f135512454b52640cfd7be95dc84be0f02281dce20247b6e6f9230a987ef61c66820268e7b766d28c1ce7aa2c550b34e294167f340205096211460415888768a48b121013711aa711634bb9ff7341a7bd072c31525875355ad"),
   770  						nil,
   771  						testutil.MustDecodeHexString("7b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d"),
   772  					),
   773  				},
   774  				Outputs: []*types.TxOutput{
   775  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   776  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("776f0a421e9176a03061d388aff4ab3b1bcd32e53a090d593a466706c69e3d3f"), 10000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   777  				},
   778  			},
   779  			err:      true,
   780  		},
   781  		{
   782  			category: "double spend",
   783  			desc:     "btm asset double spend",
   784  			insts:    []*signingInst{singleSignInst, singleSignInst},
   785  			txData: types.TxData{
   786  				Version: 1,
   787  				Inputs: []*types.TxInput{
   788  					types.NewSpendInput(nil,
   789  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   790  						*consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad"), nil),
   791  					types.NewSpendInput(nil,
   792  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   793  						*consensus.BTMAssetID, 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad"), nil),
   794  				},
   795  				Outputs: []*types.TxOutput{
   796  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 19000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   797  				},
   798  			},
   799  			err:      true,
   800  		},
   801  		{
   802  			category: "double spend",
   803  			desc:     "non btm asset double spend",
   804  			insts:    []*signingInst{singleSignInst, singleSignInst, singleSignInst},
   805  			txData: types.TxData{
   806  				Version: 1,
   807  				Inputs: []*types.TxInput{
   808  					types.NewSpendInput(nil,
   809  						bc.Hash{V0: 14760873410800997144, V1: 1698395500822741684, V2: 5965908492734661392, V3: 9445539829830863994},
   810  						*consensus.BTMAssetID, 10000000000, 0, nil, nil),
   811  					types.NewSpendInput(
   812  						nil,
   813  						bc.Hash{V0: 3485387979411255237, V1: 15603105575416882039, V2: 5974145557334619041, V3: 16513948410238218452},
   814  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad"), nil),
   815  					types.NewSpendInput(
   816  						nil,
   817  						bc.Hash{V0: 3485387979411255237, V1: 15603105575416882039, V2: 5974145557334619041, V3: 16513948410238218452},
   818  						testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 10000000000, 0, testutil.MustDecodeHexString("001420a1af4fc11399e6cd7253abf1bbd4d0af17daad"), nil),
   819  				},
   820  				Outputs: []*types.TxOutput{
   821  					types.NewOriginalTxOutput(*consensus.BTMAssetID, 9000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   822  					types.NewOriginalTxOutput(testutil.MustDecodeAsset("97575084e5161406a0977da729fbf51ad230e0ff0aec607a97e4336611c8707f"), 20000000000, testutil.MustDecodeHexString("00145931e1b7b65897f47845ac08fc136e0c0a4ff166"), nil),
   823  				},
   824  			},
   825  			err:      true,
   826  		},
   827  	}
   828  
   829  	for i, c := range cases {
   830  		mockCtrlProgram(c.txData, c.insts)
   831  
   832  		c.txData.SerializedSize = 1
   833  
   834  		tx := types.NewTx(c.txData)
   835  		mockSignTx(tx, c.insts)
   836  		bcTx := types.MapTx(&c.txData)
   837  		converter := func(prog []byte) ([]byte, error) { return nil, nil }
   838  
   839  		_, err := validation.ValidateTx(bcTx, &bc.Block{
   840  			BlockHeader:  &bc.BlockHeader{Height: 1},
   841  			Transactions: []*bc.Tx{bcTx},
   842  		}, converter)
   843  		if !c.err && err != nil {
   844  			t.Errorf("case #%d (%s) expect no error, got error %s", i, c.desc, err)
   845  		}
   846  
   847  		if c.err && err == nil {
   848  			t.Errorf("case #%d (%s) expect error, got no error", i, c.desc)
   849  		}
   850  	}
   851  }
   852  
   853  type signingInst struct {
   854  	rootPrvKeys      []string
   855  	quorum           int
   856  	keyIndex         uint64
   857  	ctrlProgramIndex uint64
   858  	change           bool
   859  }
   860  
   861  func mockCtrlProgram(txData types.TxData, insts []*signingInst) {
   862  	for i, input := range txData.Inputs {
   863  		_, xPubs := mustGetRootKeys(insts[i].rootPrvKeys)
   864  
   865  		switch inp := input.TypedInput.(type) {
   866  		case *types.SpendInput:
   867  			if inp.ControlProgram != nil {
   868  				continue
   869  			}
   870  			acc := &account.Account{Signer: &signers.Signer{KeyIndex: insts[i].keyIndex, DeriveRule: signers.BIP0044, XPubs: xPubs, Quorum: insts[i].quorum}}
   871  			program, err := account.CreateCtrlProgram(acc, insts[i].ctrlProgramIndex, insts[i].change)
   872  			if err != nil {
   873  				panic(err)
   874  			}
   875  			inp.ControlProgram = program.ControlProgram
   876  		case *types.IssuanceInput:
   877  			if inp.IssuanceProgram != nil {
   878  				continue
   879  			}
   880  			assetSigner, err := signers.Create("asset", xPubs, insts[i].quorum, insts[i].keyIndex, signers.BIP0032)
   881  			if err != nil {
   882  				panic(err)
   883  			}
   884  
   885  			path := signers.GetBip0032Path(assetSigner, signers.AssetKeySpace)
   886  			derivedXPubs := chainkd.DeriveXPubs(assetSigner.XPubs, path)
   887  			derivedPKs := chainkd.XPubKeys(derivedXPubs)
   888  
   889  			issuanceProg, err := vmutil.P2SPMultiSigProgramWithHeight(derivedPKs, insts[i].quorum, 0)
   890  			if err != nil {
   891  				panic(err)
   892  			}
   893  
   894  			inp.IssuanceProgram = issuanceProg
   895  		}
   896  	}
   897  }
   898  
   899  func mockSignTx(tx *types.Tx, insts []*signingInst) {
   900  	for i, input := range tx.TxData.Inputs {
   901  		if input.Arguments() != nil {
   902  			continue
   903  		}
   904  		var arguments [][]byte
   905  		inst := insts[i]
   906  		switch inp := input.TypedInput.(type) {
   907  		case *types.SpendInput:
   908  			path, err := signers.Path(&signers.Signer{KeyIndex: inst.keyIndex, DeriveRule: signers.BIP0044}, signers.AccountKeySpace, inst.change, inst.ctrlProgramIndex)
   909  			if err != nil {
   910  				panic(err)
   911  			}
   912  
   913  			xPrvs, xPubs := mustGetRootKeys(inst.rootPrvKeys)
   914  			for _, xPrv := range xPrvs {
   915  				childPrv := xPrv.Derive(path)
   916  				sigHashBytes := tx.SigHash(uint32(i)).Byte32()
   917  				arguments = append(arguments, childPrv.Sign(sigHashBytes[:]))
   918  			}
   919  
   920  			if len(xPrvs) == 1 {
   921  				childPrv := xPrvs[0].Derive(path)
   922  				derivePK := childPrv.XPub()
   923  				arguments = append(arguments, derivePK.PublicKey())
   924  			} else {
   925  				derivedXPubs := chainkd.DeriveXPubs(xPubs, path)
   926  				derivedPKs := chainkd.XPubKeys(derivedXPubs)
   927  				script, err := vmutil.P2SPMultiSigProgram(derivedPKs, inst.quorum)
   928  				if err != nil {
   929  					panic(err)
   930  				}
   931  
   932  				arguments = append(arguments, script)
   933  			}
   934  			inp.Arguments = arguments
   935  		case *types.IssuanceInput:
   936  			path := signers.GetBip0032Path(&signers.Signer{KeyIndex: inst.keyIndex, DeriveRule: signers.BIP0032}, signers.AssetKeySpace)
   937  			xPrvs, _ := mustGetRootKeys(inst.rootPrvKeys)
   938  			for _, xPrv := range xPrvs {
   939  				childPrv := xPrv.Derive(path)
   940  				sigHashBytes := tx.SigHash(uint32(i)).Byte32()
   941  				arguments = append(arguments, childPrv.Sign(sigHashBytes[:]))
   942  			}
   943  			inp.Arguments = arguments
   944  		}
   945  	}
   946  }
   947  
   948  func mustGetRootKeys(prvs []string) ([]chainkd.XPrv, []chainkd.XPub) {
   949  	xPubs := make([]chainkd.XPub, len(prvs))
   950  	xPrvs := make([]chainkd.XPrv, len(prvs))
   951  	for i, xPrv := range prvs {
   952  		xPrvBytes, err := hex.DecodeString(xPrv)
   953  		if err != nil {
   954  			panic(err)
   955  		}
   956  
   957  		if len(xPrvBytes) != 64 {
   958  			panic("the size of xPrv must 64")
   959  		}
   960  
   961  		var dest [64]byte
   962  		copy(dest[:], xPrv)
   963  		xPrvs[i] = chainkd.XPrv(dest)
   964  		xPubs[i] = xPrvs[i].XPub()
   965  	}
   966  	return xPrvs, xPubs
   967  }