Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

abi.gno

1.91 Kb · 81 lines
 1package types
 2
 3import "encoding/binary"
 4
 5// wrapABIEncode wraps an already-encoded dynamic ABI payload with the
 6// 32-byte offset header that Solidity prepends when a single dynamic value is
 7// returned at the top level.
 8func wrapABIEncode(encoded []byte) []byte {
 9	out := make([]byte, 0, 32+len(encoded))
10	out = append(out, u64ToH256(32)...)
11
12	return append(out, encoded...)
13}
14
15func encodeABIPacketArray(packets []Packet) ([]byte, error) {
16	out := make([]byte, 0)
17	out = append(out, u64ToH256(uint64(len(packets)))...)
18
19	headLen := len(packets) * 32
20	tail := make([]byte, 0)
21
22	for _, packet := range packets {
23		encoded, err := packet.EncodeABI()
24		if err != nil {
25			return nil, err
26		}
27
28		out = append(out, u64ToH256(uint64(headLen+len(tail)))...)
29		tail = append(tail, encoded...)
30	}
31
32	return append(out, tail...), nil
33}
34
35func encodeABIBytesArray(items [][]byte) []byte {
36	out := make([]byte, 0)
37	out = append(out, u64ToH256(uint64(len(items)))...)
38
39	headLen := len(items) * 32
40	tail := make([]byte, 0)
41
42	for _, item := range items {
43		encoded := encodeABIBytes(item)
44
45		out = append(out, u64ToH256(uint64(headLen+len(tail)))...)
46		tail = append(tail, encoded...)
47	}
48
49	return append(out, tail...)
50}
51
52// encodeABIBytes encodes bz as a Solidity `bytes` value: a 32-byte length word
53// followed by the data right-padded to a 32-byte boundary.
54func encodeABIBytes(bz []byte) []byte {
55	pad := (32 - len(bz)%32) % 32
56	out := make([]byte, 0, 32+len(bz)+pad)
57	out = append(out, u64ToH256(uint64(len(bz)))...)
58
59	out = append(out, bz...)
60	if pad > 0 {
61		out = append(out, make([]byte, pad)...)
62	}
63
64	return out
65}
66
67// u32ToH256 left-pads a uint32 into a 32-byte big-endian word.
68func u32ToH256(n uint32) []byte {
69	bz := [32]byte{}
70	binary.BigEndian.PutUint32(bz[28:], n)
71
72	return bz[:]
73}
74
75// u64ToH256 left-pads a uint64 into a 32-byte big-endian word.
76func u64ToH256(n uint64) []byte {
77	bz := [32]byte{}
78	binary.BigEndian.PutUint64(bz[24:], n)
79
80	return bz[:]
81}