github.com/cosmos/cosmos-sdk@v0.50.10/x/auth/migrations/legacytx/stdsign.go (about)

     1  package legacytx
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"sigs.k8s.io/yaml"
     8  
     9  	"cosmossdk.io/errors"
    10  
    11  	"github.com/cosmos/cosmos-sdk/codec"
    12  	"github.com/cosmos/cosmos-sdk/codec/legacy"
    13  	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    14  	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
    15  	"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
    16  	sdk "github.com/cosmos/cosmos-sdk/types"
    17  	"github.com/cosmos/cosmos-sdk/types/tx/signing"
    18  )
    19  
    20  // LegacyMsg defines the old interface a message must fulfill,
    21  // containing Amino signing method.
    22  // Deprecated: Please use `Msg` instead.
    23  type LegacyMsg interface {
    24  	sdk.Msg
    25  
    26  	// Get the canonical byte representation of the Msg.
    27  	GetSignBytes() []byte
    28  }
    29  
    30  // StdSignDoc is replay-prevention structure.
    31  // It includes the result of msg.GetSignBytes(),
    32  // as well as the ChainID (prevent cross chain replay)
    33  // and the Sequence numbers for each signature (prevent
    34  // inchain replay and enforce tx ordering per account).
    35  type StdSignDoc struct {
    36  	AccountNumber uint64            `json:"account_number" yaml:"account_number"`
    37  	Sequence      uint64            `json:"sequence" yaml:"sequence"`
    38  	TimeoutHeight uint64            `json:"timeout_height,omitempty" yaml:"timeout_height"`
    39  	ChainID       string            `json:"chain_id" yaml:"chain_id"`
    40  	Memo          string            `json:"memo" yaml:"memo"`
    41  	Fee           json.RawMessage   `json:"fee" yaml:"fee"`
    42  	Msgs          []json.RawMessage `json:"msgs" yaml:"msgs"`
    43  }
    44  
    45  var RegressionTestingAminoCodec *codec.LegacyAmino
    46  
    47  // Deprecated: please delete this code eventually.
    48  func mustSortJSON(bz []byte) []byte {
    49  	var c any
    50  	err := json.Unmarshal(bz, &c)
    51  	if err != nil {
    52  		panic(err)
    53  	}
    54  	js, err := json.Marshal(c)
    55  	if err != nil {
    56  		panic(err)
    57  	}
    58  	return js
    59  }
    60  
    61  // StdSignBytes returns the bytes to sign for a transaction.
    62  // Deprecated: Please use x/tx/signing/aminojson instead.
    63  func StdSignBytes(chainID string, accnum, sequence, timeout uint64, fee StdFee, msgs []sdk.Msg, memo string) []byte {
    64  	if RegressionTestingAminoCodec == nil {
    65  		panic(fmt.Errorf("must set RegressionTestingAminoCodec before calling StdSignBytes"))
    66  	}
    67  	msgsBytes := make([]json.RawMessage, 0, len(msgs))
    68  	for _, msg := range msgs {
    69  		bz := RegressionTestingAminoCodec.MustMarshalJSON(msg)
    70  		msgsBytes = append(msgsBytes, mustSortJSON(bz))
    71  	}
    72  
    73  	bz, err := legacy.Cdc.MarshalJSON(StdSignDoc{
    74  		AccountNumber: accnum,
    75  		ChainID:       chainID,
    76  		Fee:           json.RawMessage(fee.Bytes()),
    77  		Memo:          memo,
    78  		Msgs:          msgsBytes,
    79  		Sequence:      sequence,
    80  		TimeoutHeight: timeout,
    81  	})
    82  	if err != nil {
    83  		panic(err)
    84  	}
    85  
    86  	return mustSortJSON(bz)
    87  }
    88  
    89  // Deprecated: StdSignature represents a sig
    90  type StdSignature struct {
    91  	cryptotypes.PubKey `json:"pub_key" yaml:"pub_key"` // optional
    92  	Signature          []byte                          `json:"signature" yaml:"signature"`
    93  }
    94  
    95  // Deprecated
    96  func NewStdSignature(pk cryptotypes.PubKey, sig []byte) StdSignature {
    97  	return StdSignature{PubKey: pk, Signature: sig}
    98  }
    99  
   100  // GetSignature returns the raw signature bytes.
   101  func (ss StdSignature) GetSignature() []byte {
   102  	return ss.Signature
   103  }
   104  
   105  // GetPubKey returns the public key of a signature as a cryptotypes.PubKey using the
   106  // Amino codec.
   107  func (ss StdSignature) GetPubKey() cryptotypes.PubKey {
   108  	return ss.PubKey
   109  }
   110  
   111  // MarshalYAML returns the YAML representation of the signature.
   112  func (ss StdSignature) MarshalYAML() (interface{}, error) {
   113  	pk := ""
   114  	if ss.PubKey != nil {
   115  		pk = ss.PubKey.String()
   116  	}
   117  
   118  	bz, err := yaml.Marshal(struct {
   119  		PubKey    string `json:"pub_key"`
   120  		Signature string `json:"signature"`
   121  	}{
   122  		pk,
   123  		fmt.Sprintf("%X", ss.Signature),
   124  	})
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	return string(bz), err
   130  }
   131  
   132  func (ss StdSignature) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
   133  	return codectypes.UnpackInterfaces(ss.PubKey, unpacker)
   134  }
   135  
   136  // StdSignatureToSignatureV2 converts a StdSignature to a SignatureV2
   137  func StdSignatureToSignatureV2(cdc *codec.LegacyAmino, sig StdSignature) (signing.SignatureV2, error) {
   138  	pk := sig.GetPubKey()
   139  	data, err := pubKeySigToSigData(cdc, pk, sig.Signature)
   140  	if err != nil {
   141  		return signing.SignatureV2{}, err
   142  	}
   143  
   144  	return signing.SignatureV2{
   145  		PubKey: pk,
   146  		Data:   data,
   147  	}, nil
   148  }
   149  
   150  func pubKeySigToSigData(cdc *codec.LegacyAmino, key cryptotypes.PubKey, sig []byte) (signing.SignatureData, error) {
   151  	multiPK, ok := key.(multisig.PubKey)
   152  	if !ok {
   153  		return &signing.SingleSignatureData{
   154  			SignMode:  signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON,
   155  			Signature: sig,
   156  		}, nil
   157  	}
   158  	var multiSig multisig.AminoMultisignature
   159  	err := cdc.Unmarshal(sig, &multiSig)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	sigs := multiSig.Sigs
   165  	sigDatas := make([]signing.SignatureData, len(sigs))
   166  	pubKeys := multiPK.GetPubKeys()
   167  	bitArray := multiSig.BitArray
   168  	n := multiSig.BitArray.Count()
   169  	signatures := multisig.NewMultisig(n)
   170  	sigIdx := 0
   171  	for i := 0; i < n; i++ {
   172  		if bitArray.GetIndex(i) {
   173  			data, err := pubKeySigToSigData(cdc, pubKeys[i], multiSig.Sigs[sigIdx])
   174  			if err != nil {
   175  				return nil, errors.Wrapf(err, "Unable to convert Signature to SigData %d", sigIdx)
   176  			}
   177  
   178  			sigDatas[sigIdx] = data
   179  			multisig.AddSignature(signatures, data, sigIdx)
   180  			sigIdx++
   181  		}
   182  	}
   183  
   184  	return signatures, nil
   185  }