github.com/Finschia/finschia-sdk@v0.49.1/x/auth/legacy/legacytx/stdtx.go (about) 1 package legacytx 2 3 import ( 4 "github.com/Finschia/finschia-sdk/codec/legacy" 5 codectypes "github.com/Finschia/finschia-sdk/codec/types" 6 cryptotypes "github.com/Finschia/finschia-sdk/crypto/types" 7 sdk "github.com/Finschia/finschia-sdk/types" 8 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 9 txtypes "github.com/Finschia/finschia-sdk/types/tx" 10 "github.com/Finschia/finschia-sdk/types/tx/signing" 11 ) 12 13 // Interface implementation checks 14 var ( 15 _ sdk.Tx = (*StdTx)(nil) 16 _ sdk.TxWithMemo = (*StdTx)(nil) 17 _ sdk.FeeTx = (*StdTx)(nil) 18 _ codectypes.UnpackInterfacesMessage = (*StdTx)(nil) 19 20 _ codectypes.UnpackInterfacesMessage = (*StdSignature)(nil) 21 ) 22 23 // StdFee includes the amount of coins paid in fees and the maximum 24 // gas to be used by the transaction. The ratio yields an effective "gasprice", 25 // which must be above some miminum to be accepted into the mempool. 26 // [Deprecated] 27 type StdFee struct { 28 Amount sdk.Coins `json:"amount" yaml:"amount"` 29 Gas uint64 `json:"gas" yaml:"gas"` 30 } 31 32 // Deprecated: NewStdFee returns a new instance of StdFee 33 func NewStdFee(gas uint64, amount sdk.Coins) StdFee { 34 return StdFee{ 35 Amount: amount, 36 Gas: gas, 37 } 38 } 39 40 // GetGas returns the fee's (wanted) gas. 41 func (fee StdFee) GetGas() uint64 { 42 return fee.Gas 43 } 44 45 // GetAmount returns the fee's amount. 46 func (fee StdFee) GetAmount() sdk.Coins { 47 return fee.Amount 48 } 49 50 // Bytes returns the encoded bytes of a StdFee. 51 func (fee StdFee) Bytes() []byte { 52 if len(fee.Amount) == 0 { 53 fee.Amount = sdk.NewCoins() 54 } 55 56 bz, err := legacy.Cdc.MarshalJSON(fee) 57 if err != nil { 58 panic(err) 59 } 60 61 return bz 62 } 63 64 // GasPrices returns the gas prices for a StdFee. 65 // 66 // NOTE: The gas prices returned are not the true gas prices that were 67 // originally part of the submitted transaction because the fee is computed 68 // as fee = ceil(gasWanted * gasPrices). 69 func (fee StdFee) GasPrices() sdk.DecCoins { 70 return sdk.NewDecCoinsFromCoins(fee.Amount...).QuoDec(sdk.NewDec(int64(fee.Gas))) 71 } 72 73 // StdTx is the legacy transaction format for wrapping a Msg with Fee and Signatures. 74 // It only works with Amino, please prefer the new protobuf Tx in types/tx. 75 // NOTE: the first signature is the fee payer (Signatures must not be nil). 76 // Deprecated 77 type StdTx struct { 78 Msgs []sdk.Msg `json:"msg" yaml:"msg"` 79 Fee StdFee `json:"fee" yaml:"fee"` 80 Signatures []StdSignature `json:"signatures" yaml:"signatures"` 81 Memo string `json:"memo" yaml:"memo"` 82 TimeoutHeight uint64 `json:"timeout_height" yaml:"timeout_height"` 83 } 84 85 // Deprecated 86 func NewStdTx(msgs []sdk.Msg, fee StdFee, sigs []StdSignature, memo string) StdTx { 87 return StdTx{ 88 Msgs: msgs, 89 Fee: fee, 90 Signatures: sigs, 91 Memo: memo, 92 } 93 } 94 95 // GetMsgs returns the all the transaction's messages. 96 func (tx StdTx) GetMsgs() []sdk.Msg { return tx.Msgs } 97 98 // ValidateBasic does a simple and lightweight validation check that doesn't 99 // require access to any other information. 100 func (tx StdTx) ValidateBasic() error { 101 stdSigs := tx.GetSignatures() 102 103 if tx.Fee.Gas > txtypes.MaxGasWanted { 104 return sdkerrors.Wrapf( 105 sdkerrors.ErrInvalidRequest, 106 "invalid gas supplied; %d > %d", tx.Fee.Gas, txtypes.MaxGasWanted, 107 ) 108 } 109 if tx.Fee.Amount.IsAnyNegative() { 110 return sdkerrors.Wrapf( 111 sdkerrors.ErrInsufficientFee, 112 "invalid fee provided: %s", tx.Fee.Amount, 113 ) 114 } 115 if len(stdSigs) == 0 { 116 return sdkerrors.ErrNoSignatures 117 } 118 if len(stdSigs) != len(tx.GetSigners()) { 119 return sdkerrors.Wrapf( 120 sdkerrors.ErrUnauthorized, 121 "wrong number of signers; expected %d, got %d", len(tx.GetSigners()), len(stdSigs), 122 ) 123 } 124 125 return nil 126 } 127 128 // Deprecated: AsAny implements intoAny. It doesn't work for protobuf serialization, 129 // so it can't be saved into protobuf configured storage. We are using it only for API 130 // compatibility. 131 func (tx *StdTx) AsAny() *codectypes.Any { 132 return codectypes.UnsafePackAny(tx) 133 } 134 135 // GetSigners returns the addresses that must sign the transaction. 136 // Addresses are returned in a deterministic order. 137 // They are accumulated from the GetSigners method for each Msg 138 // in the order they appear in tx.GetMsgs(). 139 // Duplicate addresses will be omitted. 140 func (tx StdTx) GetSigners() []sdk.AccAddress { 141 var signers []sdk.AccAddress 142 seen := map[string]bool{} 143 144 for _, msg := range tx.GetMsgs() { 145 for _, addr := range msg.GetSigners() { 146 if !seen[addr.String()] { 147 signers = append(signers, addr) 148 seen[addr.String()] = true 149 } 150 } 151 } 152 153 return signers 154 } 155 156 // GetMemo returns the memo 157 func (tx StdTx) GetMemo() string { return tx.Memo } 158 159 // GetTimeoutHeight returns the transaction's timeout height (if set). 160 func (tx StdTx) GetTimeoutHeight() uint64 { 161 return tx.TimeoutHeight 162 } 163 164 // GetSignatures returns the signature of signers who signed the Msg. 165 // CONTRACT: Length returned is same as length of 166 // pubkeys returned from MsgKeySigners, and the order 167 // matches. 168 // CONTRACT: If the signature is missing (ie the Msg is 169 // invalid), then the corresponding signature is 170 // .Empty(). 171 func (tx StdTx) GetSignatures() [][]byte { 172 sigs := make([][]byte, len(tx.Signatures)) 173 for i, stdSig := range tx.Signatures { 174 sigs[i] = stdSig.Signature 175 } 176 return sigs 177 } 178 179 // GetSignaturesV2 implements SigVerifiableTx.GetSignaturesV2 180 func (tx StdTx) GetSignaturesV2() ([]signing.SignatureV2, error) { 181 res := make([]signing.SignatureV2, len(tx.Signatures)) 182 183 for i, sig := range tx.Signatures { 184 var err error 185 res[i], err = StdSignatureToSignatureV2(legacy.Cdc, sig) 186 if err != nil { 187 return nil, sdkerrors.Wrapf(err, "Unable to convert signature %v to V2", sig) 188 } 189 } 190 191 return res, nil 192 } 193 194 // GetPubkeys returns the pubkeys of signers if the pubkey is included in the signature 195 // If pubkey is not included in the signature, then nil is in the slice instead 196 func (tx StdTx) GetPubKeys() ([]cryptotypes.PubKey, error) { 197 pks := make([]cryptotypes.PubKey, len(tx.Signatures)) 198 199 for i, stdSig := range tx.Signatures { 200 pks[i] = stdSig.GetPubKey() 201 } 202 203 return pks, nil 204 } 205 206 // GetGas returns the Gas in StdFee 207 func (tx StdTx) GetGas() uint64 { return tx.Fee.Gas } 208 209 // GetFee returns the FeeAmount in StdFee 210 func (tx StdTx) GetFee() sdk.Coins { return tx.Fee.Amount } 211 212 // FeePayer returns the address that is responsible for paying fee 213 // StdTx returns the first signer as the fee payer 214 // If no signers for tx, return empty address 215 func (tx StdTx) FeePayer() sdk.AccAddress { 216 if tx.GetSigners() != nil { 217 return tx.GetSigners()[0] 218 } 219 return sdk.AccAddress{} 220 } 221 222 // FeeGranter always returns nil for StdTx 223 func (tx StdTx) FeeGranter() sdk.AccAddress { 224 return nil 225 } 226 227 func (tx StdTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { 228 for _, m := range tx.Msgs { 229 err := codectypes.UnpackInterfaces(m, unpacker) 230 if err != nil { 231 return err 232 } 233 } 234 235 // Signatures contain PubKeys, which need to be unpacked. 236 for _, s := range tx.Signatures { 237 err := s.UnpackInterfaces(unpacker) 238 if err != nil { 239 return err 240 } 241 } 242 243 return nil 244 }