How to call this SmartContract function with strings and byte-array from JavaScript using ethersJS?

I have a SmartContract that contains the following function:

pragma solidity >=0.8.0 <0.9.0;

import "./opensea/ERC1155Tradable.sol";

contract My1155 is ERC1155Tradable
{
    constructor(address _proxyRegistryAddress)
    ERC1155Tradable(
        "My1155",
        "My",
        "https://example.com/{id}",
        _proxyRegistryAddress
    ) {}

    function create(
        address _creator,
        address _initialOwner,
        uint256 _id,
        uint256 _initialSupply,
        string memory _uri,
        bytes memory _data
    ) public onlyRole(MINTER_ROLE) returns (uint256) {

        super.create(_initialOwner, _id, _initialSupply, _uri, _data);

        creators[_id] = _creator;

        return _id;
    }
    
}

From a script, I'd like to call the create-function but I can't find a proper way to to this because of strings and bytes array in the function arguments.

Using ethers.js, I have tried:

const abi = [
    'function create(\n' +
    '        address _creator,\n' +
    '        address _initialOwner,\n' +
    '        uint256 _id,\n' +
    '        uint256 _initialSupply,\n' +
    '        string memory _uri,\n' +
    '        bytes memory _data\n' +
    '    ) public'
]

const provider = new ethers.providers.InfuraProvider("rinkeby", {
    projectId: 'xxx'
}

const privateKey = process.env.PRIVATE_KEY;

const minter = new ethers.Wallet(privateKey, provider);

const contract = new ethers.Contract(tokenAddress, abi, minter);
const creator = '0xC1dAxxxx....';
const contractAddress = '0xA2dxxxx....'; // receiver

const tx = await contract.functions.create(creator, contractAddress, 1, 10, 'https://example.org/assets/erc1155/1', '');
console.log(tx);
await tx.wait();

This results in the following error:

Error: invalid arrayify value (argument="value", value="", code=INVALID_ARGUMENT, version=bytes/5.5.0)

const tx = await contract.functions.create(creator, contractAddress, 1, 10, 'https://example.org/assets/erc1155/1', '0x0');

the same error.

const tx = await contract.functions.create(creator, contractAddress, 1, 10, 'https://example.org/assets/erc1155/1', ethers.utils.toUtf8Bytes(''));

Error: cannot estimate gas; transaction may fail or may require manual
gas limit (error={"reason":"cannot estimate gas; transaction may fail
or may require manual gas limit","code":"UNPREDICTABLE_GAS_LIMIT","er

const tx = await contract.functions.create(creator, contractAddress, 1, 10, 'https://example.org/assets/erc1155/1', ethers.utils.toUtf8Bytes('0x00'));

Error: cannot estimate gas; transaction may fail or may require manual
gas limit (error={"reason":"cannot estimate gas; transaction may fail
or may require manual gas limit","code":"UNPREDICTABLE_GAS_LIMIT","er

How to achieve this function call? Many thanks in advance :slight_smile:

Hey :wave:

Have you found any solution to this? I'm stuck in a similar sitation..

It seems like you use ethers.js V4, and I think your code is ok, maybe you should use the whole function including the returning value.

function create(address _creator,address _initialOwner,uint256 _id,uint256 _initialSupply,string memory _uri,bytes memory _data)public returns (uint256)

And according to the documentation, it seems like contract.functions.create() is equal to contract.create()

1 Like