Store transactions using protobuf in default baseparser implemention
parent
d0089d2bcb
commit
feaf55e767
|
@ -2,7 +2,9 @@ package bchain
|
|||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
// BaseParser implements data parsing/handling functionality base for all other parsers
|
||||
|
@ -57,3 +59,105 @@ func (p *BaseParser) UnpackBlockHash(buf []byte) (string, error) {
|
|||
func (p *BaseParser) IsUTXOChain() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PackTx packs transaction to byte array using protobuf
|
||||
func (p *BaseParser) PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
var err error
|
||||
pti := make([]*ProtoTransaction_VinType, len(tx.Vin))
|
||||
for i, vi := range tx.Vin {
|
||||
hex, err := hex.DecodeString(vi.ScriptSig.Hex)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "Vin %v Hex %v", i, vi.ScriptSig.Hex)
|
||||
}
|
||||
itxid, err := p.PackTxid(vi.Txid)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "Vin %v Txid %v", i, vi.Txid)
|
||||
}
|
||||
pti[i] = &ProtoTransaction_VinType{
|
||||
Addresses: vi.Addresses,
|
||||
Coinbase: vi.Coinbase,
|
||||
ScriptSigHex: hex,
|
||||
Sequence: vi.Sequence,
|
||||
Txid: itxid,
|
||||
Vout: vi.Vout,
|
||||
}
|
||||
}
|
||||
pto := make([]*ProtoTransaction_VoutType, len(tx.Vout))
|
||||
for i, vo := range tx.Vout {
|
||||
hex, err := hex.DecodeString(vo.ScriptPubKey.Hex)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "Vout %v Hex %v", i, vo.ScriptPubKey.Hex)
|
||||
}
|
||||
pto[i] = &ProtoTransaction_VoutType{
|
||||
Addresses: vo.ScriptPubKey.Addresses,
|
||||
N: vo.N,
|
||||
ScriptPubKeyHex: hex,
|
||||
Value: vo.Value,
|
||||
}
|
||||
}
|
||||
pt := &ProtoTransaction{
|
||||
Blocktime: uint64(blockTime),
|
||||
Height: height,
|
||||
Locktime: tx.LockTime,
|
||||
Vin: pti,
|
||||
Vout: pto,
|
||||
}
|
||||
if pt.Hex, err = hex.DecodeString(tx.Hex); err != nil {
|
||||
return nil, errors.Annotatef(err, "Hex %v", tx.Hex)
|
||||
}
|
||||
if pt.Txid, err = p.PackTxid(tx.Txid); err != nil {
|
||||
return nil, errors.Annotatef(err, "Txid %v", tx.Txid)
|
||||
}
|
||||
return proto.Marshal(pt)
|
||||
}
|
||||
|
||||
// UnpackTx unpacks transaction from protobuf byte array
|
||||
func (p *BaseParser) UnpackTx(buf []byte) (*Tx, uint32, error) {
|
||||
var pt ProtoTransaction
|
||||
err := proto.Unmarshal(buf, &pt)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
txid, err := p.UnpackTxid(pt.Txid)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
vin := make([]Vin, len(pt.Vin))
|
||||
for i, pti := range pt.Vin {
|
||||
itxid, err := p.UnpackTxid(pti.Txid)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
vin[i] = Vin{
|
||||
Addresses: pti.Addresses,
|
||||
Coinbase: pti.Coinbase,
|
||||
ScriptSig: ScriptSig{
|
||||
Hex: hex.EncodeToString(pti.ScriptSigHex),
|
||||
},
|
||||
Sequence: pti.Sequence,
|
||||
Txid: itxid,
|
||||
Vout: pti.Vout,
|
||||
}
|
||||
}
|
||||
vout := make([]Vout, len(pt.Vout))
|
||||
for i, pto := range pt.Vout {
|
||||
vout[i] = Vout{
|
||||
N: pto.N,
|
||||
ScriptPubKey: ScriptPubKey{
|
||||
Addresses: pto.Addresses,
|
||||
Hex: hex.EncodeToString(pto.ScriptPubKeyHex),
|
||||
},
|
||||
Value: pto.Value,
|
||||
}
|
||||
}
|
||||
tx := Tx{
|
||||
Blocktime: int64(pt.Blocktime),
|
||||
Hex: hex.EncodeToString(pt.Hex),
|
||||
LockTime: pt.Locktime,
|
||||
Time: int64(pt.Blocktime),
|
||||
Txid: txid,
|
||||
Vin: vin,
|
||||
Vout: vout,
|
||||
}
|
||||
return &tx, pt.Height, nil
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/juju/errors"
|
||||
|
||||
ethcommon "github.com/ethereum/go-ethereum/common"
|
||||
|
|
|
@ -2,9 +2,6 @@ package zec
|
|||
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/gob"
|
||||
)
|
||||
|
||||
// ZCashParser handle
|
||||
|
@ -26,41 +23,3 @@ func (p *ZCashParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
|||
hash, _, err := CheckDecode(address)
|
||||
return hash, err
|
||||
}
|
||||
|
||||
// PackTx packs transaction to byte array
|
||||
func (p *ZCashParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
|
||||
buf := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(buf, height)
|
||||
buf, err := encodeTx(buf, tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func encodeTx(b []byte, tx *bchain.Tx) ([]byte, error) {
|
||||
buf := bytes.NewBuffer(b)
|
||||
enc := gob.NewEncoder(buf)
|
||||
err := enc.Encode(tx)
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
// UnpackTx unpacks transaction from byte array
|
||||
func (p *ZCashParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||
height := binary.BigEndian.Uint32(buf)
|
||||
tx, err := decodeTx(buf[4:])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return tx, height, nil
|
||||
}
|
||||
|
||||
func decodeTx(buf []byte) (*bchain.Tx, error) {
|
||||
tx := new(bchain.Tx)
|
||||
dec := gob.NewDecoder(bytes.NewBuffer(buf))
|
||||
err := dec.Decode(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx, nil
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,221 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: tx.proto
|
||||
|
||||
/*
|
||||
Package bchain is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
tx.proto
|
||||
|
||||
It has these top-level messages:
|
||||
ProtoTransaction
|
||||
*/
|
||||
package bchain
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type ProtoTransaction struct {
|
||||
Txid []byte `protobuf:"bytes,1,opt,name=Txid,proto3" json:"Txid,omitempty"`
|
||||
Hex []byte `protobuf:"bytes,2,opt,name=Hex,proto3" json:"Hex,omitempty"`
|
||||
Blocktime uint64 `protobuf:"varint,3,opt,name=Blocktime" json:"Blocktime,omitempty"`
|
||||
Locktime uint32 `protobuf:"varint,4,opt,name=Locktime" json:"Locktime,omitempty"`
|
||||
Height uint32 `protobuf:"varint,5,opt,name=Height" json:"Height,omitempty"`
|
||||
Vin []*ProtoTransaction_VinType `protobuf:"bytes,6,rep,name=Vin" json:"Vin,omitempty"`
|
||||
Vout []*ProtoTransaction_VoutType `protobuf:"bytes,7,rep,name=Vout" json:"Vout,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) Reset() { *m = ProtoTransaction{} }
|
||||
func (m *ProtoTransaction) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProtoTransaction) ProtoMessage() {}
|
||||
func (*ProtoTransaction) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
func (m *ProtoTransaction) GetTxid() []byte {
|
||||
if m != nil {
|
||||
return m.Txid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) GetHex() []byte {
|
||||
if m != nil {
|
||||
return m.Hex
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) GetBlocktime() uint64 {
|
||||
if m != nil {
|
||||
return m.Blocktime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) GetLocktime() uint32 {
|
||||
if m != nil {
|
||||
return m.Locktime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) GetHeight() uint32 {
|
||||
if m != nil {
|
||||
return m.Height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) GetVin() []*ProtoTransaction_VinType {
|
||||
if m != nil {
|
||||
return m.Vin
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction) GetVout() []*ProtoTransaction_VoutType {
|
||||
if m != nil {
|
||||
return m.Vout
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ProtoTransaction_VinType struct {
|
||||
Coinbase string `protobuf:"bytes,1,opt,name=Coinbase" json:"Coinbase,omitempty"`
|
||||
Txid []byte `protobuf:"bytes,2,opt,name=Txid,proto3" json:"Txid,omitempty"`
|
||||
Vout uint32 `protobuf:"varint,3,opt,name=Vout" json:"Vout,omitempty"`
|
||||
ScriptSigHex []byte `protobuf:"bytes,4,opt,name=ScriptSigHex,proto3" json:"ScriptSigHex,omitempty"`
|
||||
Sequence uint32 `protobuf:"varint,5,opt,name=Sequence" json:"Sequence,omitempty"`
|
||||
Addresses []string `protobuf:"bytes,6,rep,name=Addresses" json:"Addresses,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VinType) Reset() { *m = ProtoTransaction_VinType{} }
|
||||
func (m *ProtoTransaction_VinType) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProtoTransaction_VinType) ProtoMessage() {}
|
||||
func (*ProtoTransaction_VinType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
|
||||
|
||||
func (m *ProtoTransaction_VinType) GetCoinbase() string {
|
||||
if m != nil {
|
||||
return m.Coinbase
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VinType) GetTxid() []byte {
|
||||
if m != nil {
|
||||
return m.Txid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VinType) GetVout() uint32 {
|
||||
if m != nil {
|
||||
return m.Vout
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VinType) GetScriptSigHex() []byte {
|
||||
if m != nil {
|
||||
return m.ScriptSigHex
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VinType) GetSequence() uint32 {
|
||||
if m != nil {
|
||||
return m.Sequence
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VinType) GetAddresses() []string {
|
||||
if m != nil {
|
||||
return m.Addresses
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ProtoTransaction_VoutType struct {
|
||||
Value float64 `protobuf:"fixed64,1,opt,name=Value" json:"Value,omitempty"`
|
||||
N uint32 `protobuf:"varint,2,opt,name=N" json:"N,omitempty"`
|
||||
ScriptPubKeyHex []byte `protobuf:"bytes,3,opt,name=ScriptPubKeyHex,proto3" json:"ScriptPubKeyHex,omitempty"`
|
||||
Addresses []string `protobuf:"bytes,4,rep,name=Addresses" json:"Addresses,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VoutType) Reset() { *m = ProtoTransaction_VoutType{} }
|
||||
func (m *ProtoTransaction_VoutType) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProtoTransaction_VoutType) ProtoMessage() {}
|
||||
func (*ProtoTransaction_VoutType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 1} }
|
||||
|
||||
func (m *ProtoTransaction_VoutType) GetValue() float64 {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VoutType) GetN() uint32 {
|
||||
if m != nil {
|
||||
return m.N
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VoutType) GetScriptPubKeyHex() []byte {
|
||||
if m != nil {
|
||||
return m.ScriptPubKeyHex
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VoutType) GetAddresses() []string {
|
||||
if m != nil {
|
||||
return m.Addresses
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ProtoTransaction)(nil), "bchain.ProtoTransaction")
|
||||
proto.RegisterType((*ProtoTransaction_VinType)(nil), "bchain.ProtoTransaction.VinType")
|
||||
proto.RegisterType((*ProtoTransaction_VoutType)(nil), "bchain.ProtoTransaction.VoutType")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("tx.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 330 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x4e, 0xc2, 0x40,
|
||||
0x10, 0x86, 0xb3, 0xb4, 0x14, 0x18, 0x21, 0x92, 0x89, 0x31, 0x0d, 0xf1, 0x50, 0x39, 0xf5, 0xd4,
|
||||
0x03, 0xc6, 0x07, 0x50, 0x2f, 0x24, 0x1a, 0x42, 0x16, 0xd2, 0x7b, 0x5b, 0x36, 0xb0, 0x11, 0x77,
|
||||
0xb1, 0xdd, 0x1a, 0x78, 0x16, 0x1f, 0xc1, 0x97, 0x34, 0x3b, 0x2d, 0x45, 0x48, 0xbc, 0xed, 0xff,
|
||||
0xef, 0x4c, 0xff, 0x6f, 0xff, 0x14, 0xba, 0x66, 0x1f, 0xed, 0x72, 0x6d, 0x34, 0x7a, 0x69, 0xb6,
|
||||
0x49, 0xa4, 0x1a, 0x7f, 0xbb, 0x30, 0x9c, 0x5b, 0x67, 0x99, 0x27, 0xaa, 0x48, 0x32, 0x23, 0xb5,
|
||||
0x42, 0x04, 0x77, 0xb9, 0x97, 0x2b, 0x9f, 0x05, 0x2c, 0xec, 0x73, 0x3a, 0xe3, 0x10, 0x9c, 0xa9,
|
||||
0xd8, 0xfb, 0x2d, 0xb2, 0xec, 0x11, 0xef, 0xa0, 0xf7, 0xbc, 0xd5, 0xd9, 0xbb, 0x91, 0x1f, 0xc2,
|
||||
0x77, 0x02, 0x16, 0xba, 0xfc, 0x64, 0xe0, 0x08, 0xba, 0x6f, 0xc7, 0x4b, 0x37, 0x60, 0xe1, 0x80,
|
||||
0x37, 0x1a, 0x6f, 0xc1, 0x9b, 0x0a, 0xb9, 0xde, 0x18, 0xbf, 0x4d, 0x37, 0xb5, 0xc2, 0x09, 0x38,
|
||||
0xb1, 0x54, 0xbe, 0x17, 0x38, 0xe1, 0xd5, 0x24, 0x88, 0x2a, 0xc4, 0xe8, 0x12, 0x2f, 0x8a, 0xa5,
|
||||
0x5a, 0x1e, 0x76, 0x82, 0xdb, 0x61, 0x7c, 0x04, 0x37, 0xd6, 0xa5, 0xf1, 0x3b, 0xb4, 0x74, 0xff,
|
||||
0xff, 0x92, 0x2e, 0x0d, 0x6d, 0xd1, 0xf8, 0xe8, 0x87, 0x41, 0xa7, 0xfe, 0x8e, 0x45, 0x7d, 0xd1,
|
||||
0x52, 0xa5, 0x49, 0x21, 0xe8, 0xc9, 0x3d, 0xde, 0xe8, 0xa6, 0x8a, 0xd6, 0x9f, 0x2a, 0xb0, 0x8e,
|
||||
0x74, 0x08, 0x9e, 0xce, 0x38, 0x86, 0xfe, 0x22, 0xcb, 0xe5, 0xce, 0x2c, 0xe4, 0xda, 0xf6, 0xe4,
|
||||
0xd2, 0xfc, 0x99, 0x67, 0x73, 0x16, 0xe2, 0xb3, 0x14, 0x2a, 0x13, 0xf5, 0xc3, 0x1b, 0x6d, 0xcb,
|
||||
0x7c, 0x5a, 0xad, 0x72, 0x51, 0x14, 0xa2, 0xa0, 0x02, 0x7a, 0xfc, 0x64, 0x8c, 0xbe, 0xa0, 0x7b,
|
||||
0xe4, 0xc7, 0x1b, 0x68, 0xc7, 0xc9, 0xb6, 0xac, 0x50, 0x19, 0xaf, 0x04, 0xf6, 0x81, 0xcd, 0x08,
|
||||
0x72, 0xc0, 0xd9, 0x0c, 0x43, 0xb8, 0xae, 0x92, 0xe7, 0x65, 0xfa, 0x2a, 0x0e, 0x16, 0xc8, 0x21,
|
||||
0xa0, 0x4b, 0xfb, 0x3c, 0xd7, 0xbd, 0xc8, 0x4d, 0x3d, 0xfa, 0x59, 0x1e, 0x7e, 0x03, 0x00, 0x00,
|
||||
0xff, 0xff, 0x64, 0x1d, 0x38, 0xac, 0x38, 0x02, 0x00, 0x00,
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
syntax = "proto3";
|
||||
package bchain;
|
||||
|
||||
message ProtoTransaction {
|
||||
message VinType {
|
||||
string Coinbase = 1;
|
||||
bytes Txid = 2;
|
||||
uint32 Vout = 3;
|
||||
bytes ScriptSigHex = 4;
|
||||
uint32 Sequence = 5;
|
||||
repeated string Addresses = 6;
|
||||
}
|
||||
message VoutType {
|
||||
double Value = 1;
|
||||
uint32 N = 2;
|
||||
bytes ScriptPubKeyHex = 3;
|
||||
repeated string Addresses = 4;
|
||||
}
|
||||
bytes Txid = 1;
|
||||
bytes Hex = 2;
|
||||
uint64 Blocktime = 3;
|
||||
uint32 Locktime = 4;
|
||||
uint32 Height = 5;
|
||||
repeated VinType Vin = 6;
|
||||
repeated VoutType Vout = 7;
|
||||
}
|
Loading…
Reference in New Issue