code: func GetChaincodeProposalContext(prop *peer.Proposal) ([]byte, map[string][]byte, error) {
  	if prop == nil {
  		return nil, nil, errors.New("proposal is nil")
  	}
  	if len(prop.Header) == 0 {
  		return nil, nil, errors.New("proposal's header is nil")
  	}
  	if len(prop.Payload) == 0 {
  		return nil, nil, errors.New("proposal's payload is nil")
  	}
  	// get back the header
  	hdr, err := GetHeader(prop.Header)
  	if err != nil {
  		return nil, nil, errors.WithMessage(err, "error extracting header from proposal")
  	}
  	if hdr == nil {
  		return nil, nil, errors.New("unmarshaled header is nil")
  	}
  
  	chdr, err := UnmarshalChannelHeader(hdr.ChannelHeader)
  	if err != nil {
  		return nil, nil, errors.WithMessage(err, "error extracting channel header from proposal")
  	}
  
  	if err = validateChannelHeaderType(chdr, []common.HeaderType{common.HeaderType_ENDORSER_TRANSACTION, common.HeaderType_CONFIG}); err != nil {
  		return nil, nil, errors.WithMessage(err, "invalid proposal")
  	}
  
  	shdr, err := GetSignatureHeader(hdr.SignatureHeader)
  	if err != nil {
  		return nil, nil, errors.WithMessage(err, "error extracting signature header from proposal")
  	}
  
  	ccPropPayload, err := GetChaincodeProposalPayload(prop.Payload)
  	if err != nil {
  		return nil, nil, err
  	}
  
  	return shdr.Creator, ccPropPayload.TransientMap, nil
  }
docs: // GetChaincodeProposalContext returns creator and transient