OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / protocol / bc / asset.go
1 package bc
2
3 import (
4         "encoding/binary"
5         "errors"
6         "io"
7
8         "github.com/vapor/crypto/sha3pool"
9         "github.com/vapor/encoding/blockchain"
10 )
11
12 // NewAssetID convert byte array to aseet id
13 func NewAssetID(b [32]byte) (a AssetID) {
14         return AssetID{
15                 V0: binary.BigEndian.Uint64(b[0:8]),
16                 V1: binary.BigEndian.Uint64(b[8:16]),
17                 V2: binary.BigEndian.Uint64(b[16:24]),
18                 V3: binary.BigEndian.Uint64(b[24:32]),
19         }
20 }
21
22 // Byte32 return the byte array representation
23 func (a AssetID) Byte32() (b32 [32]byte) { return Hash(a).Byte32() }
24
25 // MarshalText satisfies the TextMarshaler interface.
26 func (a AssetID) MarshalText() ([]byte, error) { return Hash(a).MarshalText() }
27
28 // UnmarshalText satisfies the TextUnmarshaler interface.
29 func (a *AssetID) UnmarshalText(b []byte) error { return (*Hash)(a).UnmarshalText(b) }
30
31 // UnmarshalJSON satisfies the json.Unmarshaler interface.
32 func (a *AssetID) UnmarshalJSON(b []byte) error { return (*Hash)(a).UnmarshalJSON(b) }
33
34 // Bytes returns the byte representation.
35 func (a AssetID) Bytes() []byte { return Hash(a).Bytes() }
36
37 // WriteTo satisfies the io.WriterTo interface.
38 func (a AssetID) WriteTo(w io.Writer) (int64, error) { return Hash(a).WriteTo(w) }
39
40 // ReadFrom satisfies the io.ReaderFrom interface.
41 func (a *AssetID) ReadFrom(r io.Reader) (int64, error) { return (*Hash)(a).ReadFrom(r) }
42
43 // IsZero tells whether a Asset pointer is nil or points to an all-zero hash.
44 func (a *AssetID) IsZero() bool { return (*Hash)(a).IsZero() }
45
46 // ComputeAssetID calculate the asset id from AssetDefinition
47 func (ad *AssetDefinition) ComputeAssetID() (assetID AssetID) {
48         h := sha3pool.Get256()
49         defer sha3pool.Put256(h)
50         writeForHash(h, *ad) // error is impossible
51         var b [32]byte
52         h.Read(b[:]) // error is impossible
53         return NewAssetID(b)
54 }
55
56 // ComputeAssetID implement the assetID calculate logic
57 func ComputeAssetID(prog []byte, vmVersion uint64, data *Hash) AssetID {
58         def := &AssetDefinition{
59                 IssuanceProgram: &Program{
60                         VmVersion: vmVersion,
61                         Code:      prog,
62                 },
63                 Data: data,
64         }
65         return def.ComputeAssetID()
66 }
67
68 // ReadFrom read the AssetAmount from the bytes
69 func (a *AssetAmount) ReadFrom(r *blockchain.Reader) (err error) {
70         var assetID AssetID
71         if _, err = assetID.ReadFrom(r); err != nil {
72                 return err
73         }
74         a.AssetId = &assetID
75         a.Amount, err = blockchain.ReadVarint63(r)
76         return err
77 }
78
79 // WriteTo convert struct to byte and write to io
80 func (a AssetAmount) WriteTo(w io.Writer) (int64, error) {
81         n, err := a.AssetId.WriteTo(w)
82         if err != nil {
83                 return n, err
84         }
85         n2, err := blockchain.WriteVarint63(w, a.Amount)
86         return n + int64(n2), err
87 }
88
89 // Equal check does two AssetAmount have same assetID and amount
90 func (a *AssetAmount) Equal(other *AssetAmount) (eq bool, err error) {
91         if a == nil || other == nil {
92                 return false, errors.New("empty asset amount")
93         }
94         if a.AssetId == nil || other.AssetId == nil {
95                 return false, errors.New("empty asset id")
96         }
97         return a.Amount == other.Amount && *a.AssetId == *other.AssetId, nil
98 }