OSDN Git Service

Handle the abnormal exit situation
[bytom/vapor.git] / protocol / bc / types / bytom / types / txoutput.go
1 package types
2
3 import (
4         "io"
5
6         "github.com/vapor/encoding/blockchain"
7         "github.com/vapor/errors"
8         "github.com/vapor/protocol/bc"
9 )
10
11 // TxOutput is the top level struct of tx output.
12 type TxOutput struct {
13         AssetVersion uint64
14         OutputCommitment
15         // Unconsumed suffixes of the commitment and witness extensible strings.
16         CommitmentSuffix []byte
17 }
18
19 // NewTxOutput create a new output struct
20 func NewTxOutput(assetID bc.AssetID, amount uint64, controlProgram []byte) *TxOutput {
21         return &TxOutput{
22                 AssetVersion: 1,
23                 OutputCommitment: OutputCommitment{
24                         AssetAmount: bc.AssetAmount{
25                                 AssetId: &assetID,
26                                 Amount:  amount,
27                         },
28                         VMVersion:      1,
29                         ControlProgram: controlProgram,
30                 },
31         }
32 }
33
34 func (to *TxOutput) readFrom(r *blockchain.Reader) (err error) {
35         if to.AssetVersion, err = blockchain.ReadVarint63(r); err != nil {
36                 return errors.Wrap(err, "reading asset version")
37         }
38
39         if to.CommitmentSuffix, err = to.OutputCommitment.readFrom(r, to.AssetVersion); err != nil {
40                 return errors.Wrap(err, "reading output commitment")
41         }
42
43         // read and ignore the (empty) output witness
44         _, err = blockchain.ReadVarstr31(r)
45         return errors.Wrap(err, "reading output witness")
46 }
47
48 func (to *TxOutput) writeTo(w io.Writer) error {
49         if _, err := blockchain.WriteVarint63(w, to.AssetVersion); err != nil {
50                 return errors.Wrap(err, "writing asset version")
51         }
52
53         if err := to.writeCommitment(w); err != nil {
54                 return errors.Wrap(err, "writing output commitment")
55         }
56
57         if _, err := blockchain.WriteVarstr31(w, nil); err != nil {
58                 return errors.Wrap(err, "writing witness")
59         }
60         return nil
61 }
62
63 func (to *TxOutput) writeCommitment(w io.Writer) error {
64         return to.OutputCommitment.writeExtensibleString(w, to.CommitmentSuffix, to.AssetVersion)
65 }
66
67 // ComputeOutputID assembles an output entry given a spend commitment and
68 // computes and returns its corresponding entry ID.
69 func ComputeOutputID(sc *SpendCommitment) (h bc.Hash, err error) {
70         defer func() {
71                 if r, ok := recover().(error); ok {
72                         err = r
73                 }
74         }()
75         src := &bc.ValueSource{
76                 Ref:      &sc.SourceID,
77                 Value:    &sc.AssetAmount,
78                 Position: sc.SourcePosition,
79         }
80         o := bc.NewOutput(src, &bc.Program{VmVersion: sc.VMVersion, Code: sc.ControlProgram}, 0)
81
82         h = bc.EntryID(o)
83         return h, nil
84 }