predict.gno
2.28 Kb · 87 lines
1package zkgm
2
3import (
4 "crypto/keccak256"
5 "encoding/hex"
6
7 abi "gno.land/p/onbloc/encoding/abi"
8 types "gno.land/p/onbloc/ibc/union/types"
9 u256 "gno.land/p/onbloc/math/uint256"
10)
11
12const (
13 ibcDenomPrefix = "ibc/"
14 tagCallProxy = "ZKGM_CALL_PROXY"
15)
16
17// PredictWrappedToken derives the legacy wrapped IBC denom for a v1 token order.
18func PredictWrappedToken(path *u256.Uint, channelId uint32, baseToken []byte) string {
19 if path == nil {
20 path = u256.Zero()
21 }
22
23 bz, err := abi.Encode(PredictWrappedTokenSchema, []any{path, channelId, baseToken})
24 if err != nil {
25 panic(err)
26 }
27
28 h := keccak256.Sum256(bz)
29
30 return ibcDenomPrefix + hex.EncodeToString(h[:20])
31}
32
33// PredictWrappedTokenV2 derives the IBC voucher denom for a v2 token order.
34func PredictWrappedTokenV2(path *u256.Uint, channelId uint32, baseToken []byte, metadataImage [32]byte) string {
35 if path == nil {
36 path = u256.Zero()
37 }
38
39 image := u256.Zero().SetBytes(metadataImage[:])
40
41 bz, err := abi.Encode(PredictV2Schema, []any{path, channelId, baseToken, image})
42 if err != nil {
43 panic(err)
44 }
45
46 h := keccak256.Sum256(bz)
47
48 return ibcDenomPrefix + hex.EncodeToString(h[:20])
49}
50
51// MetadataImage returns keccak256(TokenMetadata), the on-chain identity of the
52// metadata used to mint a voucher.
53func MetadataImage(meta TokenMetadata) [32]byte {
54 bz, err := EncodeTokenMetadata(meta)
55 if err != nil {
56 panic(err)
57 }
58
59 return keccak256.Sum256(bz)
60}
61
62// Uint256FromBytes32 converts a big-endian bytes32 value into a uint256.
63func Uint256FromBytes32(bz [32]byte) *u256.Uint {
64 return u256.Zero().SetBytes(bz[:])
65}
66
67// PredictCallProxyAccount returns the synthetic Gno address that represents
68// the given (path, destinationChannel, sender) tuple as a callable account.
69//
70// key = zkgm1<first-20-bytes-of-keccak(ZKGM_CALL_PROXY || path || channelId || sender)>
71func PredictCallProxyAccount(path *u256.Uint, channelId types.ChannelId, sender []byte) string {
72 var pathBytes [32]byte
73 if path != nil {
74 pathBytes = Uint256ToBytes32(path)
75 }
76
77 channel := channelId.String()
78 buf := make([]byte, 0, len(tagCallProxy)+len(pathBytes)+len(channel)+len(sender))
79 buf = append(buf, tagCallProxy...)
80 buf = append(buf, pathBytes[:]...)
81 buf = append(buf, channel...)
82 buf = append(buf, sender...)
83
84 h := keccak256.Sum256(buf)
85
86 return "zkgm1" + hex.EncodeToString(h[:20])
87}