deep_copy.go
func callAminoCopy(src, dst reflect.Value) bool {
	if src.Type() != dst.Type() {
		panic("should not happen")
	}
	if src.Kind() == reflect.Ptr {
		cpy := reflect.New(src.Type().Elem())
		dst.Set(cpy)
	} else if src.CanAddr() {
		if !dst.CanAddr() {
			panic("should not happen")
		}
		src = src.Addr()
		dst = dst.Addr()
	} else {
		return false
	}
	if !canAminoCopy(src) {
		return false
	}
	cpy := reflect.New(src.Type().Elem())
	dst.Set(cpy)
	ma := src.MethodByName("MarshalAmino")
	ua := dst.MethodByName("UnmarshalAmino")
	outs := ma.Call(nil)
	repr, err := outs[0], outs[1]
	if !err.IsNil() {
		panic(err.Interface())
	}
	outs = ua.Call([]reflect.Value{repr})
	err = outs[0]
	if !err.IsNil() {
		panic(err.Interface())
	}
	return true
}
func callAminoCopy(src, dst reflect.Value) bool {
	if src.Type() != dst.Type() {
		panic("should not happen")
	}
	if src.Kind() == reflect.Ptr {
		cpy := reflect.New(src.Type().Elem())
		dst.Set(cpy)
	} else if src.CanAddr() {
		if !dst.CanAddr() {
			panic("should not happen")
		}
		src = src.Addr()
		dst = dst.Addr()
	} else {
		return false
	}
	if !canAminoCopy(src) {
		return false
	}
	cpy := reflect.New(src.Type().Elem())
	dst.Set(cpy)
	ma := src.MethodByName("MarshalAmino")
	ua := dst.MethodByName("UnmarshalAmino")
	outs := ma.Call(nil)
	repr, err := outs[0], outs[1]
	if !err.IsNil() {
		panic(err.Interface())
	}
	outs = ua.Call([]reflect.Value{repr})
	err = outs[0]
	if !err.IsNil() {
		panic(err.Interface())
	}
	return true
}
// Call .MarshalAmino() and .UnmarshalAmino to copy if possible.
// Panics if .MarshalAmino() or .UnmarshalAmino() return an error.
// CONTRACT: src and dst are of equal types.