2018-03-04 13:56:49 +00:00
|
|
|
package transaction
|
|
|
|
|
|
|
|
import (
|
2020-02-25 15:32:10 +00:00
|
|
|
"sort"
|
|
|
|
|
2019-09-16 09:18:13 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
2018-03-21 16:11:04 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/util"
|
2018-03-04 13:56:49 +00:00
|
|
|
)
|
|
|
|
|
2019-02-20 17:39:32 +00:00
|
|
|
// Input represents a Transaction input (CoinReference).
|
2018-03-04 13:56:49 +00:00
|
|
|
type Input struct {
|
|
|
|
// The hash of the previous transaction.
|
2019-02-20 17:39:32 +00:00
|
|
|
PrevHash util.Uint256 `json:"txid"`
|
2018-03-04 13:56:49 +00:00
|
|
|
|
|
|
|
// The index of the previous transaction.
|
2019-02-20 17:39:32 +00:00
|
|
|
PrevIndex uint16 `json:"vout"`
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
|
|
|
|
2019-09-16 16:31:49 +00:00
|
|
|
// DecodeBinary implements Serializable interface.
|
|
|
|
func (in *Input) DecodeBinary(br *io.BinReader) {
|
2019-12-06 15:37:46 +00:00
|
|
|
br.ReadBytes(in.PrevHash[:])
|
2019-12-12 15:52:23 +00:00
|
|
|
in.PrevIndex = br.ReadU16LE()
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
|
|
|
|
2019-09-16 16:31:49 +00:00
|
|
|
// EncodeBinary implements Serializable interface.
|
|
|
|
func (in *Input) EncodeBinary(bw *io.BinWriter) {
|
2019-12-06 15:22:21 +00:00
|
|
|
bw.WriteBytes(in.PrevHash[:])
|
2019-12-12 15:52:23 +00:00
|
|
|
bw.WriteU16LE(in.PrevIndex)
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
2020-02-25 15:32:10 +00:00
|
|
|
|
|
|
|
// GroupInputsByPrevHash groups all TX inputs by their previous hash into
|
|
|
|
// several slices (which actually are subslices of one new slice with pointers).
|
|
|
|
// Each of these slices contains at least one element.
|
|
|
|
func GroupInputsByPrevHash(ins []Input) [][]*Input {
|
|
|
|
if len(ins) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
ptrs := make([]*Input, len(ins))
|
|
|
|
for i := range ins {
|
|
|
|
ptrs[i] = &ins[i]
|
|
|
|
}
|
|
|
|
sort.Slice(ptrs, func(i, j int) bool {
|
|
|
|
return ptrs[i].PrevHash.CompareTo(ptrs[j].PrevHash) < 0
|
|
|
|
})
|
|
|
|
|
|
|
|
var first int
|
|
|
|
res := make([][]*Input, 0)
|
|
|
|
currentHash := ptrs[0].PrevHash
|
|
|
|
|
|
|
|
for i := range ptrs {
|
|
|
|
if !currentHash.Equals(ptrs[i].PrevHash) {
|
|
|
|
res = append(res, ptrs[first:i])
|
|
|
|
first = i
|
|
|
|
currentHash = ptrs[i].PrevHash
|
|
|
|
}
|
|
|
|
}
|
|
|
|
res = append(res, ptrs[first:])
|
|
|
|
return res
|
|
|
|
}
|