Search code examples
nearprotocolassemblyscriptaurora-near

How to encode arguments in AssemblyScript when calling Aurora contract from Near blockchain?


I'm trying to call a contract located in Aurora from a contract located in Near. I'm using AssemblyScript and I'm struggling with passing arguments to the Aurora contract itself. I receive ERR_BORSH_DESERIALIZE panic from the Aurora contract. Can anybody help me with figuring out how I would encode arguments? Here is sample code:

import { BorshSerializer } from '@serial-as/borsh'

@serializable
class FunctionCallArgs {
  contract: Uint8Array;
  input: Uint8Array;
}

export function myFunction(): void {
  const args: FunctionCallArgs = {
    contract: util.stringToBytes(contractAddress),
    input: util.stringToBytes(abiEncodedFn),
  };
  const argsBorsh = BorshSerializer.encode(args);

  ContractPromise.create("aurora", "call", argsBorsh, 100);
}

Solution

  • I managed to find a solution. The flow of calling the contract was right, however I had two errors in implementation.

    1. Wrong conversion of the contract address to 20 byte array. My custom implementation of the function a bit verbose, so here is a single line JS script that does the same:
    Buffer.from(contractAddress.substring(2), 'hex') // removing 0x prefix is mandatory
    
    1. "@serial-as/borsh" doesn't deserialize fixed length arrays. So I had to convert contractAddress (which is Uint8Array after converting it to bytes in 1st point) to StaticArray(20), like this:
    const contract = hexToBytes(tokenAddress).reduce((memo, v, i) => {
      memo[i] = <u8>v;
      return memo;
    }, new StaticArray<u8>(20);
    

    And finally monkey-patched "encode_static_array" method in the library to not allocate space before adding bytes to buffer. So removed:

    encode_static_array<T>(value: StaticArray<T>): void {
      ...
      this.buffer.store<u32>(value.length); // remove this line
      ...
    }