// ParseTransfer parses and performs sanity checks on the payload of a transfer transaction.
ParseTransfer parses and performs sanity checks on the payload of a transfer transaction.
// ParseTransfer parses and performs sanity checks on the payload of a transfer transaction .
func ParseTransfer(payload []byte) (Transfer, error) {
	r := bytes.NewReader(payload)
	b := make([]byte, 8)
	var transfer Transfer
	if _, err := io.ReadFull(r, transfer.Recipient[:]); err != nil {
		return transfer, errors.Wrap(err, "transfer: failed to decode recipient")
	}
	if _, err := io.ReadFull(r, b); err != nil {
		return transfer, errors.Wrap(err, "transfer: failed to decode amount of PERLs to send")
	}
	transfer.Amount = binary.LittleEndian.Uint64(b)
	if r.Len() > 0 {
		if _, err := io.ReadFull(r, b); err != nil {
			return transfer, errors.Wrap(err, "transfer: failed to decode gas limit")
		}
		transfer.GasLimit = binary.LittleEndian.Uint64(b)
	}
	if r.Len() > 0 {
		if _, err := io.ReadFull(r, b[:8]); err != nil {
			return transfer, errors.Wrap(err, "transfer: failed to decode gas deposit")
		}
		transfer.GasDeposit = binary.LittleEndian.Uint64(b)
	}
	if r.Len() > 0 {
		if _, err := io.ReadFull(r, b[:4]); err != nil {
			return transfer, errors.Wrap(err, "transfer: failed to decode size of smart contract function name to invoke")
		}
		size := binary.LittleEndian.Uint32(b[:4])
		if size > 1024 {
			return transfer, errors.New("transfer: smart contract function name exceeds 1024 characters")
		}
		transfer.FuncName = make([]byte, size)
		if _, err := io.ReadFull(r, transfer.FuncName); err != nil {
			return transfer, errors.Wrap(err, "transfer: failed to decode smart contract function name to invoke")
		}
		if string(transfer.FuncName) == "init" {
			return transfer, errors.New("transfer: not allowed to call init function for smart contract")
		}
	}
	if r.Len() > 0 {
		if _, err := io.ReadFull(r, b[:4]); err != nil {
			return transfer, errors.Wrap(
				err, "transfer: failed to decode number of smart contract function invocation parameters",
			)
		}
		size := binary.LittleEndian.Uint32(b[:4])
		if size > 1*1024*1024 {
			return transfer, errors.New("transfer: smart contract payload exceeds 1MB")
		}
		transfer.FuncParams = make([]byte, size)
		if _, err := io.ReadFull(r, transfer.FuncParams); err != nil {
			return transfer, errors.Wrap(
				err, "transfer: failed to decode smart contract function invocation parameters",
			)
		}
	}
	if transfer.GasLimit == 0 && len(transfer.FuncName) > 0 {
		return transfer, errors.New(
			"transfer: gas limit for invoking smart contract function must be greater than zero",
		)
	}
	return transfer, nil
}
func ParseTransfer ( payload [ ] byte ) ( Transfer , error ) { r := bytes . NewReader ( payload ) b := make ( [ ] byte , 8 ) var transfer Transfer if _ , err := io . ReadFull ( r , transfer . Recipient [ : ] ) ; err != nil { return transfer , errors . Wrap ( err , " " ) } if _ , err := io . ReadFull ( r , b ) ; err != nil { return transfer , errors . Wrap ( err , " " ) } transfer . Amount = binary . LittleEndian . Uint64 ( b ) if r . Len ( ) > 0 { if _ , err := io . ReadFull ( r , b ) ; err != nil { return transfer , errors . Wrap ( err , " " ) } transfer . GasLimit = binary . LittleEndian . Uint64 ( b ) } if r . Len ( ) > 0 { if _ , err := io . ReadFull ( r , b [ : 8 ] ) ; err != nil { return transfer , errors . Wrap ( err , " " ) } transfer . GasDeposit = binary . LittleEndian . Uint64 ( b ) } if r . Len ( ) > 0 { if _ , err := io . ReadFull ( r , b [ : 4 ] ) ; err != nil { return transfer , errors . Wrap ( err , " " ) } size := binary . LittleEndian . Uint32 ( b [ : 4 ] ) if size > 1024 { return transfer , errors . New ( " " ) } transfer . FuncName = make ( [ ] byte , size ) if _ , err := io . ReadFull ( r , transfer . FuncName ) ; err != nil { return transfer , errors . Wrap ( err , " " ) } if string ( transfer . FuncName ) == " " { return transfer , errors . New ( " " ) } } if r . Len ( ) > 0 { if _ , err := io . ReadFull ( r , b [ : 4 ] ) ; err != nil { return transfer , errors . Wrap ( err , " " , ) } size := binary . LittleEndian . Uint32 ( b [ : 4 ] ) if size > 1 * 1024 * 1024 { return transfer , errors . New ( " " ) } transfer . FuncParams = make ( [ ] byte , size ) if _ , err := io . ReadFull ( r , transfer . FuncParams ) ; err != nil { return transfer , errors . Wrap ( err , " " , ) } } if transfer . GasLimit == 0 && len ( transfer . FuncName ) > 0 { return transfer , errors . New ( " " , ) } return transfer , nil }
ParseTransfer parses and performs sanity checks on the payload of a transfer transaction.
ParseTransfer parses and performs sanity checks on the payload of a transfer transaction .