-
Notifications
You must be signed in to change notification settings - Fork 147
/
nft.go
92 lines (83 loc) · 2.05 KB
/
nft.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package isc
import (
"github.com/iotaledger/hive.go/serializer/v2"
"github.com/iotaledger/hive.go/serializer/v2/marshalutil"
iotago "github.com/iotaledger/iota.go/v3"
)
type NFT struct {
ID iotago.NFTID
Issuer iotago.Address
Metadata []byte // (ImmutableMetadata)
Owner AgentID // can be nil
}
func (nft *NFT) Bytes(withID ...bool) []byte {
writeID := true
if len(withID) > 0 {
writeID = withID[0]
}
mu := marshalutil.New()
if writeID {
mu.WriteBytes(nft.ID[:])
}
issuerBytes, err := nft.Issuer.Serialize(serializer.DeSeriModeNoValidation, nil)
if err != nil {
panic("Unexpected error serializing NFT")
}
mu.WriteBytes(issuerBytes)
mu.WriteUint16(uint16(len(nft.Metadata)))
mu.WriteBytes(nft.Metadata)
if nft.Owner != nil {
mu.WriteBytes(nft.Owner.Bytes())
}
return mu.Bytes()
}
func NFTFromMarshalUtil(mu *marshalutil.MarshalUtil, withID ...bool) (*NFT, error) {
readID := true
if len(withID) > 0 {
readID = withID[0]
}
ret := &NFT{}
if readID {
idBytes, err := mu.ReadBytes(iotago.NFTIDLength)
if err != nil {
return nil, err
}
copy(ret.ID[:], idBytes)
}
currentOffset := mu.ReadOffset()
issuerAddrType, err := mu.ReadByte()
if err != nil {
return nil, err
}
ret.Issuer, err = iotago.AddressSelector(uint32(issuerAddrType)) // this is silly, it gets casted to `byte` again inside
if err != nil {
return nil, err
}
mu.ReadSeek(-1)
bytesRead, err := ret.Issuer.Deserialize(mu.ReadRemainingBytes(), serializer.DeSeriModeNoValidation, nil)
if err != nil {
return nil, err
}
mu.ReadSeek(currentOffset + bytesRead)
metadataLen, err := mu.ReadUint16()
if err != nil {
return nil, err
}
ret.Metadata, err = mu.ReadBytes(int(metadataLen))
if err != nil {
return nil, err
}
if done, err2 := mu.DoneReading(); err2 != nil {
return nil, err2
} else if done {
return ret, nil
}
ret.Owner, err = AgentIDFromMarshalUtil(mu)
if err != nil {
return nil, err
}
return ret, nil
}
func NFTFromBytes(bytes []byte, withID ...bool) (*NFT, error) {
return NFTFromMarshalUtil(marshalutil.New(bytes), withID...)
}