code.vegaprotocol.io/vega@v0.79.0/core/bridges/erc20_common.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package bridges 17 18 import ( 19 "bytes" 20 "encoding/hex" 21 "fmt" 22 23 "code.vegaprotocol.io/vega/core/nodewallets/eth/clef" 24 "code.vegaprotocol.io/vega/libs/num" 25 26 "github.com/ethereum/go-ethereum/accounts/abi" 27 ethcmn "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/crypto" 29 ) 30 31 var prefix = []byte{0x19} 32 33 type Signer interface { 34 Sign([]byte) ([]byte, error) 35 Algo() string 36 } 37 38 type SignaturePayload struct { 39 Message Bytes 40 Signature Bytes 41 } 42 43 type Bytes []byte 44 45 func (b Bytes) Bytes() []byte { 46 return b 47 } 48 49 func (b Bytes) Hex() string { 50 return hex.EncodeToString(b) 51 } 52 53 func packScheme( 54 buf []byte, submitter, chainID string, v1 bool, 55 ) ([]byte, error) { 56 if v1 { 57 return packSchemeV1(buf, submitter) 58 } 59 return packSchemeV2(buf, submitter, chainID) 60 } 61 62 // packSchemeV1 returns the payload to be hashed and signed where 63 // payload = abi.encode(message, msg.sender). 64 func packSchemeV1( 65 buf []byte, submitter string, 66 ) ([]byte, error) { 67 typBytes, err := abi.NewType("bytes", "", nil) 68 if err != nil { 69 return nil, err 70 } 71 typAddr, err := abi.NewType("address", "", nil) 72 if err != nil { 73 return nil, err 74 } 75 76 submitterAddr := ethcmn.HexToAddress(submitter) 77 args2 := abi.Arguments([]abi.Argument{ 78 { 79 Name: "bytes", 80 Type: typBytes, 81 }, 82 { 83 Name: "address", 84 Type: typAddr, 85 }, 86 }) 87 88 return args2.Pack(buf, submitterAddr) 89 } 90 91 // packSchemeV2 returns the payload to be hashed and signed where 92 // payload = abi.encodePacked(bytes1(0x19), block.chainid, abi.encode(message, msg.sender)) 93 // where abi.encodePacked is the concatenation of the individual byte slices. 94 func packSchemeV2( 95 buf []byte, submitter, chainID string, 96 ) ([]byte, error) { 97 typBytes, err := abi.NewType("bytes", "", nil) 98 if err != nil { 99 return nil, err 100 } 101 typAddr, err := abi.NewType("address", "", nil) 102 if err != nil { 103 return nil, err 104 } 105 106 submitterAddr := ethcmn.HexToAddress(submitter) 107 args := abi.Arguments([]abi.Argument{ 108 { 109 Name: "bytes", 110 Type: typBytes, 111 }, 112 { 113 Name: "address", 114 Type: typAddr, 115 }, 116 }) 117 118 // abi.encode(message, msg.sender) 119 buf, err = args.Pack(buf, submitterAddr) 120 if err != nil { 121 return nil, err 122 } 123 124 // concat(prefix, chain-id, abi.encode(message, msg.sender)) 125 cid := num.MustUintFromString(chainID, 10).Bytes() 126 return bytes.Join([][]byte{prefix, cid[:], buf}, nil), nil 127 } 128 129 func sign(signer Signer, msg []byte) (*SignaturePayload, error) { 130 var sig []byte 131 var err error 132 133 if signer.Algo() == clef.ClefAlgoType { 134 sig, err = signer.Sign(msg) 135 } else { 136 // hash our message before signing it 137 hash := crypto.Keccak256(msg) 138 sig, err = signer.Sign(hash) 139 } 140 141 if err != nil { 142 return nil, fmt.Errorf("could not sign message with ethereum wallet: %w", err) 143 } 144 return &SignaturePayload{ 145 Message: msg, 146 Signature: sig, 147 }, nil 148 }