code: func (t *Transactor) RequestRedeem(request *token.RedeemRequest) (*token.TokenTransaction, error) {
  	if len(request.GetTokenIds()) == 0 {
  		return nil, errors.New("no token ids in RedeemRequest")
  	}
  	if request.GetQuantityToRedeem() <= 0 {
  		return nil, errors.Errorf("quantity to redeem [%d] must be greater than 0", request.GetQuantityToRedeem())
  	}
  
  	inputs, tokenType, quantitySum, err := t.getInputsFromTokenIds(request.GetTokenIds())
  	if err != nil {
  		return nil, err
  	}
  
  	if quantitySum < request.QuantityToRedeem {
  		return nil, errors.Errorf("total quantity [%d] from TokenIds is less than quantity [%d] to be redeemed", quantitySum, request.QuantityToRedeem)
  	}
  
  	// add the output for redeem itself
  	var outputs []*token.PlainOutput
  	outputs = append(outputs, &token.PlainOutput{
  		Type:     tokenType,
  		Quantity: request.QuantityToRedeem,
  	})
  
  	// add another output if there is remaining quantity after redemption
  	if quantitySum > request.QuantityToRedeem {
  		outputs = append(outputs, &token.PlainOutput{
  			Owner:    t.PublicCredential, // PublicCredential is serialized identity for the creator
  			Type:     tokenType,
  			Quantity: quantitySum - request.QuantityToRedeem,
  		})
  	}
  
  	// PlainRedeem shares the same data structure as PlainTransfer
  	transaction := &token.TokenTransaction{
  		Action: &token.TokenTransaction_PlainAction{
  			PlainAction: &token.PlainTokenAction{
  				Data: &token.PlainTokenAction_PlainRedeem{
  					PlainRedeem: &token.PlainTransfer{
  						Inputs:  inputs,
  						Outputs: outputs,
  					},
  				},
  			},
  		},
  	}
  
  	return transaction, nil
  }
docs: // RequestRedeem creates a TokenTransaction of type redeem request