6 "github.com/bytom/encoding/blockchain"
7 "github.com/bytom/errors"
8 "github.com/bytom/protocol/bc"
11 // TODO(bobg): Review serialization/deserialization logic for
12 // assetVersions other than 1.
14 type TxOutput struct {
18 // Unconsumed suffixes of the commitment and witness extensible strings.
19 CommitmentSuffix []byte
25 func NewTxOutput(assetID bc.AssetID, amount uint64, controlProgram, referenceData []byte) *TxOutput {
28 OutputCommitment: OutputCommitment{
29 AssetAmount: bc.AssetAmount{
34 ControlProgram: controlProgram,
36 ReferenceData: referenceData,
40 func (to *TxOutput) readFrom(r *blockchain.Reader, txVersion uint64) (err error) {
41 to.AssetVersion, err = blockchain.ReadVarint63(r)
43 return errors.Wrap(err, "reading asset version")
46 to.CommitmentSuffix, err = to.OutputCommitment.readFrom(r, to.AssetVersion)
48 return errors.Wrap(err, "reading output commitment")
51 to.ReferenceData, err = blockchain.ReadVarstr31(r)
53 return errors.Wrap(err, "reading reference data")
56 // read and ignore the (empty) output witness
57 _, err = blockchain.ReadVarstr31(r)
59 return errors.Wrap(err, "reading output witness")
62 func (to *TxOutput) writeTo(w io.Writer, serflags byte) error {
63 if _, err := blockchain.WriteVarint63(w, to.AssetVersion); err != nil {
64 return errors.Wrap(err, "writing asset version")
67 if err := to.WriteCommitment(w); err != nil {
68 return errors.Wrap(err, "writing output commitment")
71 if err := writeRefData(w, to.ReferenceData, serflags); err != nil {
72 return errors.Wrap(err, "writing reference data")
75 // write witness (empty in v1)
76 if _, err := blockchain.WriteVarstr31(w, nil); err != nil {
77 return errors.Wrap(err, "writing witness")
82 func (to *TxOutput) WriteCommitment(w io.Writer) error {
83 return to.OutputCommitment.writeExtensibleString(w, to.CommitmentSuffix, to.AssetVersion)
86 func (to *TxOutput) CommitmentHash() bc.Hash {
87 return to.OutputCommitment.Hash(to.CommitmentSuffix, to.AssetVersion)
90 // ComputeOutputID assembles an output entry given a spend commitment
91 // and computes and returns its corresponding entry ID.
92 func ComputeOutputID(sc *SpendCommitment) (h bc.Hash, err error) {
94 if r, ok := recover().(error); ok {
98 src := &bc.ValueSource{
100 Value: &sc.AssetAmount,
101 Position: sc.SourcePosition,
103 o := bc.NewOutput(src, &bc.Program{VmVersion: sc.VMVersion, Code: sc.ControlProgram}, &sc.RefDataHash, 0)