11 "github.com/davecgh/go-spew/spew"
13 "github.com/vapor/common"
14 "github.com/vapor/consensus"
15 "github.com/vapor/crypto"
16 "github.com/vapor/crypto/ed25519/chainkd"
17 chainjson "github.com/vapor/encoding/json"
18 "github.com/vapor/errors"
19 "github.com/vapor/protocol/bc"
20 "github.com/vapor/protocol/bc/types"
21 "github.com/vapor/protocol/vm/vmutil"
22 "github.com/vapor/testutil"
25 type testAction bc.AssetAmount
27 func (t testAction) Build(ctx context.Context, b *TemplateBuilder) error {
28 in := types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), *t.AssetId, t.Amount, 0, nil)
29 tplIn := &SigningInstruction{}
31 err := b.AddInput(in, tplIn)
35 return b.AddOutput(types.NewIntraChainOutput(*t.AssetId, t.Amount, []byte("change")))
38 func (t testAction) ActionType() string {
42 func newControlProgramAction(assetAmt bc.AssetAmount, script []byte) *controlProgramAction {
43 return &controlProgramAction{
44 AssetAmount: assetAmt,
49 func TestBuildIntra(t *testing.T) {
50 ctx := context.Background()
52 assetID1 := bc.NewAssetID([32]byte{1})
53 assetID2 := bc.NewAssetID([32]byte{2})
56 newControlProgramAction(bc.AssetAmount{AssetId: &assetID2, Amount: 6}, []byte("dest")),
57 testAction(bc.AssetAmount{AssetId: &assetID1, Amount: 5}),
59 expiryTime := time.Now().Add(time.Minute)
60 got, err := Build(ctx, nil, actions, expiryTime, 0)
66 Transaction: types.NewTx(types.TxData{
68 Inputs: []*types.TxInput{
69 types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), assetID1, 5, 0, nil),
71 Outputs: []*types.TxOutput{
72 types.NewIntraChainOutput(assetID2, 6, []byte("dest")),
73 types.NewIntraChainOutput(assetID1, 5, []byte("change")),
76 SigningInstructions: []*SigningInstruction{{
77 WitnessComponents: []witnessComponent{},
81 if !testutil.DeepEqual(got.Transaction.TxData, want.Transaction.TxData) {
82 t.Errorf("got tx:\n%s\nwant tx:\n%s", spew.Sdump(got.Transaction.TxData), spew.Sdump(want.Transaction.TxData))
85 if !testutil.DeepEqual(got.SigningInstructions, want.SigningInstructions) {
86 t.Errorf("got signing instructions:\n\t%#v\nwant signing instructions:\n\t%#v", got.SigningInstructions, want.SigningInstructions)
90 func newCrossOutAction(assetAmt bc.AssetAmount, redeemContract []byte) *crossOutAction {
91 address, err := common.NewAddressWitnessPubKeyHash(redeemContract, consensus.BytomMainNetParams(&consensus.ActiveNetParams))
96 return &crossOutAction{
97 AssetAmount: assetAmt,
98 Address: address.String(),
102 func TestBuildCrossOut(t *testing.T) {
103 ctx := context.Background()
105 assetID1 := bc.NewAssetID([32]byte{1})
106 assetID2 := bc.NewAssetID([32]byte{2})
108 redeemContract := make([]byte, 20)
109 controlProgram := append([]byte{0x00, byte(len(redeemContract))}, redeemContract...)
112 newCrossOutAction(bc.AssetAmount{AssetId: &assetID2, Amount: 6}, redeemContract),
113 testAction(bc.AssetAmount{AssetId: &assetID1, Amount: 5}),
115 expiryTime := time.Now().Add(time.Minute)
116 got, err := Build(ctx, nil, actions, expiryTime, 0)
122 Transaction: types.NewTx(types.TxData{
124 Inputs: []*types.TxInput{
125 types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), assetID1, 5, 0, nil),
127 Outputs: []*types.TxOutput{
128 types.NewCrossChainOutput(assetID2, 6, controlProgram),
129 types.NewIntraChainOutput(assetID1, 5, []byte("change")),
132 SigningInstructions: []*SigningInstruction{{
133 WitnessComponents: []witnessComponent{},
137 if !testutil.DeepEqual(got.Transaction.TxData, want.Transaction.TxData) {
138 t.Errorf("got tx:\n%s\nwant tx:\n%s", spew.Sdump(got.Transaction.TxData), spew.Sdump(want.Transaction.TxData))
141 if !testutil.DeepEqual(got.SigningInstructions, want.SigningInstructions) {
142 t.Errorf("got signing instructions:\n\t%#v\nwant signing instructions:\n\t%#v", got.SigningInstructions, want.SigningInstructions)
146 func mustDecodeHex(str string) []byte {
147 data, err := hex.DecodeString(str)
154 func TestCheckBlankCheck(t *testing.T) {
160 Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil)},
165 Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil)},
166 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 3, nil)},
171 Inputs: []*types.TxInput{
172 types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil),
173 types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.NewAssetID([32]byte{1}), 5, 0, nil),
175 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 5, nil)},
180 Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil)},
181 Outputs: []*types.TxOutput{
182 types.NewIntraChainOutput(bc.AssetID{}, math.MaxInt64, nil),
183 types.NewIntraChainOutput(bc.AssetID{}, 7, nil),
189 Inputs: []*types.TxInput{
190 types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil),
191 types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, math.MaxInt64, 0, nil),
197 Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil)},
198 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 5, nil)},
203 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 5, nil)},
208 Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), bc.AssetID{}, 5, 0, nil)},
209 Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.NewAssetID([32]byte{1}), 5, nil)},
214 for _, c := range cases {
215 got := checkBlankCheck(c.tx)
216 if errors.Root(got) != c.want {
217 t.Errorf("checkUnsafe(%+v) err = %v want %v", c.tx, errors.Root(got), c.want)
222 func TestCreateTxByUtxo(t *testing.T) {
223 xprv, xpub, err := chainkd.NewXKeys(nil)
228 pub := xpub.PublicKey()
229 pubHash := crypto.Ripemd160(pub)
230 program, err := vmutil.P2WPKHProgram([]byte(pubHash))
235 address, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.ActiveNetParams)
240 muxID := testutil.MustDecodeHash("1e673900965623ec3305cead5a78dfb68a34599f8bc078460f3f202256c3dfa6")
246 ControlProgram []byte
250 AssetID: *consensus.BTMAssetID,
253 ControlProgram: program,
254 Address: address.EncodeAddress(),
257 recvProg := mustDecodeHex("00145056532ecd3621c9ce8adde5505c058610b287cf")
258 tx := types.NewTx(types.TxData{
260 Inputs: []*types.TxInput{
261 types.NewSpendInput(nil, utxo.SourceID, utxo.AssetID, utxo.Amount, utxo.SourcePos, utxo.ControlProgram),
263 Outputs: []*types.TxOutput{
264 types.NewIntraChainOutput(*consensus.BTMAssetID, 10000000000, recvProg),
270 AllowAdditional: false,
273 h := tpl.Hash(0).Byte32()
274 sig := xprv.Sign(h[:])
277 // Test with more signatures than required, in correct order
278 tpl.SigningInstructions = []*SigningInstruction{{
279 WitnessComponents: []witnessComponent{
282 Sigs: []chainjson.HexBytes{sig},
288 if err = materializeWitnesses(tpl); err != nil {
292 if !testutil.DeepEqual(tx, tpl.Transaction) {
293 t.Errorf("tx:%v result is equal to want:%v", tx, tpl.Transaction)
297 func TestAddContractArgs(t *testing.T) {
298 hexXpub, err := hex.DecodeString("ba76bb52574b3f40315f2c01f1818a9072ced56e9d4b68acbef56a4d0077d08e5e34837963e4cdc54eb251aa34aad01e6ae48b140f6a2743fbb0a0abd9cf8aac")
303 var xpub chainkd.XPub
304 copy(xpub[:], hexXpub)
306 rawTxSig := RawTxSigArgument{RootXPub: xpub, Path: []chainjson.HexBytes{{1, 1, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 0}}}
307 rawTxSigMsg, err := json.Marshal(rawTxSig)
312 value, err := hex.DecodeString("7468697320697320612074657374")
316 data := DataArgument{value}
317 dataMsg, err := json.Marshal(data)
322 strMsg, err := json.Marshal(StrArgument{"this is a test string"})
327 integerMsg, err := json.Marshal(IntegerArgument{100})
332 boolMsg, err := json.Marshal(BoolArgument{true})
338 arguments []ContractArgument
342 arguments: []ContractArgument{
344 Type: "raw_tx_signature",
345 RawData: rawTxSigMsg,
351 arguments: []ContractArgument{
360 arguments: []ContractArgument{
369 arguments: []ContractArgument{
378 arguments: []ContractArgument{
387 arguments: []ContractArgument{
389 Type: "raw_tx_signature",
390 RawData: rawTxSigMsg,
400 arguments: []ContractArgument{
406 Type: "raw_tx_signature",
407 RawData: rawTxSigMsg,
413 arguments: []ContractArgument{
415 Type: "raw_tx_signature",
416 RawData: rawTxSigMsg,
438 arguments: []ContractArgument{
445 RawData: rawTxSigMsg,
448 wantResult: ErrBadContractArgType,
452 sigInst := &SigningInstruction{}
453 for _, c := range cases {
454 err := AddContractArgs(sigInst, c.arguments)
455 if err != c.wantResult {
456 t.Fatalf("got result=%v, want result=%v", err, c.wantResult)