2018-03-04 13:56:49 +00:00
|
|
|
package transaction
|
|
|
|
|
|
|
|
import (
|
2019-02-20 17:39:32 +00:00
|
|
|
"encoding/hex"
|
|
|
|
"encoding/json"
|
2018-03-17 11:53:21 +00:00
|
|
|
"fmt"
|
2018-03-04 13:56:49 +00:00
|
|
|
|
2019-09-16 09:18:13 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
2018-03-04 13:56:49 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Attribute represents a Transaction attribute.
|
|
|
|
type Attribute struct {
|
|
|
|
Usage AttrUsage
|
|
|
|
Data []byte
|
|
|
|
}
|
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
// DecodeBinary implements the Payload interface.
|
2019-09-16 09:18:13 +00:00
|
|
|
func (attr *Attribute) DecodeBinary(br *io.BinReader) error {
|
2019-08-28 16:27:06 +00:00
|
|
|
br.ReadLE(&attr.Usage)
|
|
|
|
|
|
|
|
// very special case
|
2018-03-04 13:56:49 +00:00
|
|
|
if attr.Usage == ECDH02 || attr.Usage == ECDH03 {
|
|
|
|
attr.Data = make([]byte, 33)
|
|
|
|
attr.Data[0] = byte(attr.Usage)
|
2019-08-28 16:27:06 +00:00
|
|
|
br.ReadLE(attr.Data[1:])
|
|
|
|
return br.Err
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
2019-08-28 16:27:06 +00:00
|
|
|
var datasize uint64
|
|
|
|
switch attr.Usage {
|
|
|
|
case ContractHash, Vote, Hash1, Hash2, Hash3, Hash4, Hash5,
|
|
|
|
Hash6, Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13,
|
|
|
|
Hash14, Hash15:
|
|
|
|
datasize = 32
|
|
|
|
case Script:
|
|
|
|
datasize = 20
|
|
|
|
case DescriptionURL:
|
2019-08-30 12:35:38 +00:00
|
|
|
// It's not VarUint as per C# implementation, dunno why
|
|
|
|
var urllen uint8
|
|
|
|
br.ReadLE(&urllen)
|
|
|
|
datasize = uint64(urllen)
|
2019-08-28 16:27:06 +00:00
|
|
|
case Description, Remark, Remark1, Remark2, Remark3, Remark4,
|
|
|
|
Remark5, Remark6, Remark7, Remark8, Remark9, Remark10, Remark11,
|
|
|
|
Remark12, Remark13, Remark14, Remark15:
|
|
|
|
datasize = br.ReadVarUint()
|
|
|
|
default:
|
2019-08-30 07:42:53 +00:00
|
|
|
return fmt.Errorf("failed decoding TX attribute usage: 0x%2x", int(attr.Usage))
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
2019-08-28 16:27:06 +00:00
|
|
|
attr.Data = make([]byte, datasize)
|
|
|
|
br.ReadLE(attr.Data)
|
|
|
|
return br.Err
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// EncodeBinary implements the Payload interface.
|
2019-09-16 09:18:13 +00:00
|
|
|
func (attr *Attribute) EncodeBinary(bw *io.BinWriter) error {
|
2019-08-28 16:27:06 +00:00
|
|
|
bw.WriteLE(&attr.Usage)
|
|
|
|
switch attr.Usage {
|
|
|
|
case ECDH02, ECDH03:
|
|
|
|
bw.WriteLE(attr.Data[1:])
|
2019-08-30 12:35:38 +00:00
|
|
|
case Description, Remark, Remark1, Remark2, Remark3, Remark4,
|
2019-08-28 16:27:06 +00:00
|
|
|
Remark5, Remark6, Remark7, Remark8, Remark9, Remark10, Remark11,
|
|
|
|
Remark12, Remark13, Remark14, Remark15:
|
2019-08-30 12:35:38 +00:00
|
|
|
bw.WriteBytes(attr.Data)
|
|
|
|
case DescriptionURL:
|
2019-09-03 15:06:16 +00:00
|
|
|
var urllen = uint8(len(attr.Data))
|
2019-08-30 12:35:38 +00:00
|
|
|
bw.WriteLE(urllen)
|
2019-08-28 16:27:06 +00:00
|
|
|
fallthrough
|
2019-09-09 08:23:27 +00:00
|
|
|
case Script, ContractHash, Vote, Hash1, Hash2, Hash3, Hash4, Hash5, Hash6,
|
2019-08-28 16:27:06 +00:00
|
|
|
Hash7, Hash8, Hash9, Hash10, Hash11, Hash12, Hash13, Hash14, Hash15:
|
|
|
|
bw.WriteLE(attr.Data)
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Usage)
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
2019-08-28 16:27:06 +00:00
|
|
|
|
|
|
|
return bw.Err
|
2018-03-04 13:56:49 +00:00
|
|
|
}
|
2019-02-20 17:39:32 +00:00
|
|
|
|
|
|
|
// MarshalJSON implements the json Marschaller interface
|
|
|
|
func (attr *Attribute) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(map[string]string{
|
|
|
|
"usage": attr.Usage.String(),
|
|
|
|
"data": hex.EncodeToString(attr.Data),
|
|
|
|
})
|
|
|
|
}
|