Decode an ethers js Uint8Array

ethers.jssolidity

Say I have a Uint8Array of length 32(i.e. 256 bits) how do I decode that array based on type. For example abi.encode(-100) as a byte array is Array(31).fill(255).concat([9]) which can also be expressed as the following hexstring: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c.

How do I decode the (32 bytes)byte array in ethers js by specifying its type for generic solidity types? The ether js documentation discussing byte arrays doesn't explain how to decode it.

Decoding the byte array should return the input value to abi.encode for the following functions.

pragma solidity >=0.7.0 <0.9.0;

contract AbiEncode {

    function encodeUint16(uint16 _uint16) public pure returns (bytes memory){
        // abi.encode(100) == 0x0000000000000000000000000000000000000000000000000000000000000064
        return abi.encode(_uint16);
    }

    function encodeInt16(int16 _int16) public pure returns (bytes memory){
        // abi.encode(-100) == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c
        return abi.encode(_int16);
    }

    function encodeAddress(address _address) public pure returns (bytes memory){
        // abi.encode(0xf8e81D47203A594245E36C48e151709F0C19fBe8) == 0x000000000000000000000000f8e81d47203a594245e36c48e151709f0c19fbe8
        return abi.encode(_address);
    }

    function encodeBool(bool _bool) public pure returns (bytes memory){
        // abi.encode(true) == 0x0000000000000000000000000000000000000000000000000000000000000001
        return abi.encode(_bool);
    }    
}

Best Answer

I've managed to get it working thanks in part to this answer.

import {
  utils
} from 'ethers'; // v5.5.4

// returnBytesArray is of type Uint8Array where each 32 bytes encodes a single value
const returnHexString = utils.hexlify(returnBytesArray); 

const decodedRetVal = utils.defaultAbiCoder.decode(
  ['int16'], // specify your return type/s here
  utils.hexDataSlice(returnHexString, 0)
);
Related Topic