Repository: gakonst/ethers-rs (rust)

Issue:
the trait `TokenizableItem` is not implemented for `ethers::prelude::Bytes`
**Version**
0.6.0

**Platform**
```
Darwin Mac-mini.local 21.2.0 Darwin Kernel Version 21.2.0: Sun Nov 28 20:29:10 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T8101 arm64                                                                                                                            /0.0s
```
**Description**
Generated ABI for https://github.com/sushiswap/bentobox/blob/canary/deployments/mainnet/BentoBoxV1.json with `Abigen.generate`. However, it doesn't seem to compile because of a missing trait implementation. Fails at `BatchCall`

```rs
    #[doc = "Container type for all input parameters for the `batch`function with signature `batch(bytes[],bool)` and selector `[210, 66, 59, 81]`"]
    #[derive(
        Clone,
        Debug,
        Default,
        Eq,
        PartialEq,
        ethers :: contract :: EthCall,
        ethers :: contract :: EthDisplay,
    )]
    #[ethcall(name = "batch", abi = "batch(bytes[],bool)")]
    pub struct BatchCall {
        pub calls: ::std::vec::Vec<ethers::core::types::Bytes>,
        pub revert_on_fail: bool,
    }
```

Error:
```
error[E0277]: the trait bound `ethers::prelude::Bytes: TokenizableItem` is not satisfied
   --> src/contracts/IBentoBoxV1.rs:895:9
    |
895 |         ethers :: contract :: EthCall,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TokenizableItem` is not implemented for `ethers::prelude::Bytes`
    |
    = note: required because of the requirements on the impl of `Tokenizable` for `Vec<ethers::prelude::Bytes>`
    = note: required because of the requirements on the impl of `Tokenize` for `Vec<ethers::prelude::Bytes>`
    = help: see issue #48214
    = note: this error originates in the derive macro `ethers::contract::EthCall` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ethers::prelude::Bytes: TokenizableItem` is not satisfied
   --> src/contracts/IBentoBoxV1.rs:895:9
    |
895 |         ethers :: contract :: EthCall,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TokenizableItem` is not implemented for `ethers::prelude::Bytes`
    |
    = note: required because of the requirements on the impl of `Tokenizable` for `Vec<ethers::prelude::Bytes>`
    = note: required because of the requirements on the impl of `Tokenize` for `Vec<ethers::prelude::Bytes>`
    = note: 1 redundant requirement hidden
    = note: required because of the requirements on the impl of `Tokenizable` for `BatchCall`
note: required by a bound in `EthCall`
```

I am guessing abigen is missing code for handling bytes arrays -- `bytes[]`


Pull request description:
feat(codec): impl codec for Bytes
<!--
Thank you for your Pull Request. Please provide a description above and review
the requirements below.

Bug fixes and new features should include tests.

Contributors guide: https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md

The contributors guide includes instructions for running rustfmt and building the
documentation.
-->

## Motivation
Closes #855
<!--
Explain the context and why you're making that change. What is the problem
you're trying to solve? In some cases there is not a problem and this can be
thought of as being the motivation for your change.
-->

## Solution

<!--
Summarize the solution and provide any necessary context needed to understand
the code change.
-->

## PR Checklist

- [x] Added Tests
- [ ] Added Documentation
- [ ] Updated the changelog


Patch:
diff --git a/ethers-core/src/abi/codec.rs b/ethers-core/src/abi/codec.rs
index f4de400c..fef30f18 100644
--- a/ethers-core/src/abi/codec.rs
+++ b/ethers-core/src/abi/codec.rs
@@ -2,7 +2,7 @@ use crate::{
     abi::{
         AbiArrayType, AbiError, AbiType, Detokenize, Token, Tokenizable, TokenizableItem, Tokenize,
     },
-    types::{Address, H256, U128, U256},
+    types::{Address, Bytes, H256, U128, U256},
 };
 
 /// Trait for ABI encoding
@@ -40,6 +40,7 @@ macro_rules! impl_abi_codec {
 
 impl_abi_codec!(
     Vec<u8>,
+    Bytes,
     Address,
     bool,
     String,
@@ -228,4 +229,11 @@ mod tests {
         .collect::<String>()
         };
     }
+
+    #[test]
+    fn bytes_codec() {
+        let bytes: Bytes = std::iter::repeat_with(random::<u8>).take(10).collect::<Vec<_>>().into();
+        let v = vec![bytes];
+        assert_codec(v);
+    }
 }


Test patch:
diff --git a/ethers-contract/tests/common/derive.rs b/ethers-contract/tests/common/derive.rs
index 58c0aa83..a18879d3 100644
--- a/ethers-contract/tests/common/derive.rs
+++ b/ethers-contract/tests/common/derive.rs
@@ -3,7 +3,7 @@ use ethers_contract::{
 };
 use ethers_core::{
     abi::{AbiDecode, AbiEncode, RawLog, Tokenizable},
-    types::{Address, H160, H256, I256, U128, U256},
+    types::{Address, Bytes, H160, H256, I256, U128, U256},
 };
 
 fn assert_tokenizeable<T: Tokenizable>() {}
@@ -560,3 +560,15 @@ fn can_derive_abi_codec_two_field() {
 
     assert_eq!(decoded_wrapped, tuple);
 }
+
+#[test]
+fn can_derive_ethcall_for_bytes() {
+    #[derive(Clone, Debug, Default, Eq, PartialEq, EthCall, EthDisplay)]
+    #[ethcall(name = "batch", abi = "batch(bytes[],bool)")]
+    pub struct BatchCall {
+        pub calls: Vec<Bytes>,
+        pub revert_on_fail: bool,
+    }
+
+    assert_ethcall::<BatchCall>();
+}