OSDN Git Service

fix ErrLoadKey in multi-sig witness (#506)
[bytom/bytom.git] / protocol / bc / bctest / tx.go
1 // Package bctest provides utilities for constructing blockchain data
2 // structures.
3 package bctest
4
5 import (
6         "crypto/rand"
7         "testing"
8
9         "golang.org/x/crypto/sha3"
10
11         "github.com/bytom/crypto/ed25519/chainkd"
12         "github.com/bytom/protocol/bc"
13         "github.com/bytom/protocol/bc/types"
14         "github.com/bytom/protocol/vm"
15         "github.com/bytom/protocol/vm/vmutil"
16         "github.com/bytom/testutil"
17 )
18
19 // NewIssuanceTx creates a new signed, issuance transaction issuing 100 units
20 // of a new asset to a garbage control program. The resulting transaction has
21 // one input and one output.
22 //
23 // The asset issued is created from randomly-generated keys. The resulting
24 // transaction is finalized (signed with a TXSIGHASH commitment).
25 func NewIssuanceTx(tb testing.TB, initial bc.Hash, opts ...func(*types.Tx)) *types.Tx {
26         // Generate a random key pair for the asset being issued.
27         xprv, xpub, err := chainkd.NewXKeys(nil)
28         if err != nil {
29                 testutil.FatalErr(tb, err)
30         }
31         pubkeys := chainkd.XPubKeys([]chainkd.XPub{xpub})
32
33         // Create a corresponding issuance program.
34         sigProg, err := vmutil.P2SPMultiSigProgram(pubkeys, 1)
35         if err != nil {
36                 testutil.FatalErr(tb, err)
37         }
38         builder := vmutil.NewBuilder()
39         builder.AddRawBytes(sigProg)
40         issuanceProgram, _ := builder.Build()
41
42         // Create a transaction issuing this new asset.
43         var nonce [8]byte
44         _, err = rand.Read(nonce[:])
45         if err != nil {
46                 testutil.FatalErr(tb, err)
47         }
48         assetdef := []byte(`{"type": "prottest issuance"}`)
49         txin := types.NewIssuanceInput(nonce[:], 100, issuanceProgram, nil, assetdef)
50
51         tx := types.NewTx(types.TxData{
52                 Version: 1,
53                 Inputs:  []*types.TxInput{txin},
54                 Outputs: []*types.TxOutput{
55                         types.NewTxOutput(txin.AssetID(), 100, []byte{0xbe, 0xef}),
56                 },
57         })
58
59         for _, opt := range opts {
60                 opt(tx)
61         }
62
63         // Sign with a simple TXSIGHASH signature.
64         builder = vmutil.NewBuilder()
65         h := tx.SigHash(0)
66         builder.AddData(h.Bytes())
67         builder.AddOp(vm.OP_TXSIGHASH).AddOp(vm.OP_EQUAL)
68         sigprog, _ := builder.Build()
69         sigproghash := sha3.Sum256(sigprog)
70         signature := xprv.Sign(sigproghash[:])
71
72         var witness [][]byte
73         witness = append(witness, vm.Int64Bytes(0)) // 0 args to the sigprog
74         witness = append(witness, signature)
75         witness = append(witness, sigprog)
76         tx.SetInputArguments(0, witness)
77
78         return tx
79 }