func (payload ExtEthCompatPayload) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	abiBytes, err := payload.ABI.MarshalBinary()
	if err != nil {
		return nil, err
	}
	if err := binary.Write(buf, binary.LittleEndian, abiBytes); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write ExtEthCompatPayload.ABI: %v", err)
	}
	valueBytes, err := payload.Value.MarshalBinary()
	if err != nil {
		return nil, err
	}
	if err := binary.Write(buf, binary.LittleEndian, valueBytes); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write ExtEthCompatPayload.Value: %v", err)
	}
	fnBytes, err := payload.Fn.MarshalBinary()
	if err != nil {
		return nil, err
	}
	if err := binary.Write(buf, binary.LittleEndian, fnBytes); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write ExtEthCompatPayload.Fn: %v", err)
	}
	return buf.Bytes(), nil
}
MarshalBinary implements the `encoding.BinaryMarshaler` interface for the
ExtEthCompatPayload type.
package v0
import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"math/big"
	"sort"
	"strings"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
)
const (
	ExtTypeEthCompatAddress = "ext_ethCompatAddress"
	ExtTypeBtcCompatUTXO    = "ext_btcCompatUTXO"
	ExtTypeBtcCompatUTXOs   = "ext_btcCompatUTXOs"
	ExtTypeEthCompatTx      = "ext_ethCompatTx"
	ExtTypeEthCompatPayload = "ext_ethCompatPayload"
)
type ExtEthCompatAddress common.Address
func ExtEthCompatAddressFromHex(str string) (ExtEthCompatAddress, error) {
	if strings.HasPrefix(str, "0x") {
		str = str[2:]
	}
	h, err := hex.DecodeString(str)
	if err != nil {
		return ExtEthCompatAddress{}, err
	}
	if len(h) != 20 {
		return ExtEthCompatAddress{}, fmt.Errorf("expected %v bytes, got %v byte", 20, len(h))
	}
	extEthCompatAddress := [20]byte{}
	copy(extEthCompatAddress[:], h)
	return ExtEthCompatAddress(extEthCompatAddress), nil
}
func (ExtEthCompatAddress) Type() Type {
	return ExtTypeEthCompatAddress
}
func (extEthCompatAddress ExtEthCompatAddress) Equal(other Value) bool {
	if other.Type() != ExtTypeEthCompatAddress {
		return false
	}
	val := other.(ExtEthCompatAddress)
	return bytes.Equal(extEthCompatAddress[:], val[:])
}
func (extEthCompatAddress ExtEthCompatAddress) MarshalJSON() ([]byte, error) {
	return json.Marshal(extEthCompatAddress.String())
}
func (extEthCompatAddress *ExtEthCompatAddress) UnmarshalJSON(data []byte) error {
	var v string
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}
	vBytes, err := hex.DecodeString(v)
	if err != nil {
		return err
	}
	copy(extEthCompatAddress[:], vBytes)
	return nil
}
func (extEthCompatAddress ExtEthCompatAddress) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	if err := binary.Write(buf, binary.LittleEndian, extEthCompatAddress); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extEthCompatAddress data: %v", err)
	}
	return buf.Bytes(), nil
}
func (extEthCompatAddress *ExtEthCompatAddress) UnmarshalBinary(data []byte) error {
	buf := bytes.NewBuffer(data)
	if err := binary.Read(buf, binary.LittleEndian, extEthCompatAddress); err != nil {
		return fmt.Errorf("cannot read extEthCompatAddress data: %v", err)
	}
	return nil
}
func (extEthCompatAddress ExtEthCompatAddress) String() string {
	return hex.EncodeToString(extEthCompatAddress[:])
}
type ExtBtcCompatUTXOs []ExtBtcCompatUTXO
func (utxos ExtBtcCompatUTXOs) Equal(other Value) bool {
	otherUTXOs, ok := other.(ExtBtcCompatUTXOs)
	if !ok {
		return false
	}
	if len(utxos) != len(otherUTXOs) {
		return false
	}
	if len(utxos) == 0 {
		return true
	}
	for i := range utxos {
		if !utxos[i].Equal(otherUTXOs[i]) {
			return false
		}
	}
	return true
}
func (ExtBtcCompatUTXOs) Type() Type {
	return ExtTypeBtcCompatUTXOs
}
func (extBtcCompatUTXOs ExtBtcCompatUTXOs) Amount() U256 {
	total := big.NewInt(0)
	for _, utxo := range extBtcCompatUTXOs {
		total = new(big.Int).Add(total, utxo.Amount.Int)
	}
	return U256{Int: total}
}
func (utxos ExtBtcCompatUTXOs) Sort() {
	sort.SliceStable(utxos, func(i, j int) bool {
		return utxos[i].Amount.Int.Cmp(utxos[j].Amount.Int) == -1
	})
}
func (extBtcCompatUTXOs ExtBtcCompatUTXOs) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	if err := binary.Write(buf, binary.LittleEndian, uint64(len(extBtcCompatUTXOs))); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXOs len: %v", err)
	}
	for _, extBtcCompatUTXO := range extBtcCompatUTXOs {
		extBtcCompatUTXOData, err := extBtcCompatUTXO.MarshalBinary()
		if err != nil {
			return buf.Bytes(), fmt.Errorf("cannot marshal extBtcCompatUTXO: %v", err)
		}
		if err := binary.Write(buf, binary.LittleEndian, uint64(len(extBtcCompatUTXOData))); err != nil {
			return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO len: %v", err)
		}
		if err := binary.Write(buf, binary.LittleEndian, extBtcCompatUTXOData); err != nil {
			return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO data: %v", err)
		}
	}
	return buf.Bytes(), nil
}
func (extBtcCompatUTXOs *ExtBtcCompatUTXOs) UnmarshalBinary(data []byte) error {
	buf := bytes.NewBuffer(data)
	var lenExtBtcCompatUTXOs uint64
	if err := binary.Read(buf, binary.LittleEndian, &lenExtBtcCompatUTXOs); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXOs len: %v", err)
	}
	if lenExtBtcCompatUTXOs > 4096 {
		return fmt.Errorf("cannot read extBtcCompatUTXOs: too many")
	}
	extBtcCompatUTXOsList := make(ExtBtcCompatUTXOs, lenExtBtcCompatUTXOs)
	var numBytes uint64
	for i := uint64(0); i < lenExtBtcCompatUTXOs; i++ {
		if err := binary.Read(buf, binary.LittleEndian, &numBytes); err != nil {
			return fmt.Errorf("cannot read extBtcCompatUTXO len: %v", err)
		}
		if numBytes > 10*1024 {
			return fmt.Errorf("cannot read extBtcCompatUTXO: too many bytes")
		}
		extBtcCompatUTXOBytes := make([]byte, numBytes)
		if _, err := buf.Read(extBtcCompatUTXOBytes); err != nil {
			return fmt.Errorf("cannot read extBtcCompatUTXO data: %v", err)
		}
		if err := extBtcCompatUTXOsList[i].UnmarshalBinary(extBtcCompatUTXOBytes); err != nil {
			return fmt.Errorf("cannot unmarshal extBtcCompatUTXO: %v", err)
		}
	}
	*extBtcCompatUTXOs = extBtcCompatUTXOsList
	return nil
}
type ExtBtcCompatUTXO struct {
	TxHash B32 `json:"txHash"`
	VOut   U32 `json:"vOut"`
	ScriptPubKey B    `json:"scriptPubKey,omitempty"`
	Amount       U256 `json:"amount,omitempty"`
	GHash        B32  `json:"ghash,omitempty"`
}
func (ExtBtcCompatUTXO) Type() Type {
	return ExtTypeBtcCompatUTXO
}
func (utxo ExtBtcCompatUTXO) Equal(other Value) bool {
	otherUTXO, ok := other.(ExtBtcCompatUTXO)
	if !ok {
		return false
	}
	return utxo.TxHash.Equal(otherUTXO.TxHash) &&
		utxo.VOut.Equal(otherUTXO.VOut) &&
		utxo.ScriptPubKey.Equal(otherUTXO.ScriptPubKey) &&
		utxo.Amount.Equal(otherUTXO.Amount) &&
		utxo.GHash.Equal(otherUTXO.GHash)
}
func (extBtcCompatUTXO ExtBtcCompatUTXO) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	if err := binary.Write(buf, binary.LittleEndian, extBtcCompatUTXO.TxHash); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO.TxHash data: %v", err)
	}
	vOutBytes, err := extBtcCompatUTXO.VOut.MarshalBinary()
	if err != nil {
		return buf.Bytes(), fmt.Errorf("cannot marshal extBtcCompatUTXO.VOut: %v", err)
	}
	if err := binary.Write(buf, binary.LittleEndian, vOutBytes); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO.VOut data: %v", err)
	}
	if err := binary.Write(buf, binary.LittleEndian, uint64(len(extBtcCompatUTXO.ScriptPubKey))); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO.ScriptPubKey len: %v", err)
	}
	if err := binary.Write(buf, binary.LittleEndian, extBtcCompatUTXO.ScriptPubKey); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO.ScriptPubKey data: %v", err)
	}
	amountBytes, err := extBtcCompatUTXO.Amount.MarshalBinary()
	if err != nil {
		return buf.Bytes(), fmt.Errorf("cannot marshal extBtcCompatUTXO.Amount: %v", err)
	}
	if err := binary.Write(buf, binary.LittleEndian, amountBytes); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO.Amount data: %v", err)
	}
	if err := binary.Write(buf, binary.LittleEndian, extBtcCompatUTXO.GHash); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extBtcCompatUTXO.GHash data: %v", err)
	}
	return buf.Bytes(), nil
}
func (extBtcCompatUTXO *ExtBtcCompatUTXO) UnmarshalBinary(data []byte) error {
	buf := bytes.NewBuffer(data)
	if err := binary.Read(buf, binary.LittleEndian, &extBtcCompatUTXO.TxHash); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXO.TxHash data: %v", err)
	}
	vOutBytes := make([]byte, 4)
	if _, err := buf.Read(vOutBytes); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXO.VOut data: %v", err)
	}
	if err := extBtcCompatUTXO.VOut.UnmarshalBinary(vOutBytes); err != nil {
		return fmt.Errorf("cannot unmarshal extBtcCompatUTXO.VOut: %v", err)
	}
	var numBytes uint64
	if err := binary.Read(buf, binary.LittleEndian, &numBytes); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXO.ScriptPubKey len: %v", err)
	}
	if numBytes > 1024 {
		return fmt.Errorf("cannot read extBtcCompatUTXO: too many bytes")
	}
	scriptPubKeyBytes := make([]byte, numBytes)
	if _, err := buf.Read(scriptPubKeyBytes); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXO.ScriptPubKey data: %v", err)
	}
	extBtcCompatUTXO.ScriptPubKey = scriptPubKeyBytes
	amountBytes := make([]byte, 32)
	if _, err := buf.Read(amountBytes); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXO.Amount data: %v", err)
	}
	if err := extBtcCompatUTXO.Amount.UnmarshalBinary(amountBytes); err != nil {
		return fmt.Errorf("cannot unmarshal extBtcCompatUTXO.Amount: %v", err)
	}
	if err := binary.Read(buf, binary.LittleEndian, &extBtcCompatUTXO.GHash); err != nil {
		return fmt.Errorf("cannot read extBtcCompatUTXO.GHash data: %v", err)
	}
	return nil
}
type ExtEthCompatTx struct {
	TxHash B32 `json:"txHash"`
}
func (ExtEthCompatTx) Type() Type {
	return ExtTypeEthCompatTx
}
func (tx ExtEthCompatTx) Equal(other Value) bool {
	otherTx, ok := other.(ExtEthCompatTx)
	if !ok {
		return false
	}
	return tx.TxHash.Equal(otherTx.TxHash)
}
func (extEthCompatTx ExtEthCompatTx) MarshalBinary() ([]byte, error) {
	buf := new(bytes.Buffer)
	if err := binary.Write(buf, binary.LittleEndian, extEthCompatTx.TxHash); err != nil {
		return buf.Bytes(), fmt.Errorf("cannot write extEthCompatTx.TxHash data: %v", err)
	}
	return buf.Bytes(), nil
}
func (extEthCompatTx *ExtEthCompatTx) UnmarshalBinary(data []byte) error {
	buf := bytes.NewBuffer(data)
	if err := binary.Read(buf, binary.LittleEndian, &extEthCompatTx.TxHash); err != nil {
		return fmt.Errorf("cannot read extEthCompatTx.TxHash data: %v", err)
	}
	return nil
}
type ExtEthCompatPayload struct {
	ABI   B `json:"abi"`
	Value B `json:"value"`
	Fn    B `json:"fn"`
}
func (ExtEthCompatPayload) Type() Type {
	return ExtTypeEthCompatPayload
}
func (payload ExtEthCompatPayload) Equal(other Value) bool {
	otherPayload, ok := other.(ExtEthCompatPayload)
	if !ok {
		return false
	}
	return payload.ABI.Equal(otherPayload.ABI) && payload.Value.Equal(otherPayload.Value) && payload.Fn.Equal(otherPayload.Fn)
}