Jump to content

Erdjs SmartContract 'call' - chainID problem


julian
 Share

Recommended Posts

Hi, I try to understand if I can use @elrondnetwork/erdjs (v8.0.0 but also v8.0.1-alpha.5) and SmartContract 'call' function, which uses Transaction under the hood. The problem is that I don't see a way to pass the ChainID where Transaction accepts that. So 'call' looks like this:

call({ func, args, value, gasLimit, receiver }: CallArguments): Transaction {
        args = args || [];
        value = value || Balance.Zero();

        let payload = TransactionPayload.contractCall()
            .setFunction(func)
            .setArgs(args)
            .build();

        let transaction = new Transaction({
            receiver: receiver ? receiver : this.getAddress(),
            value: value,
            gasLimit: gasLimit,
            data: payload
        });

        transaction.onSigned.on(this.onCallSigned.bind(this));

        return transaction;
    }

There is no option to pass the ChainID to Transaction. And it won't use proper chain id if I, for example, set up the 'dapp' with devnet config.

So if I won't pass the chainId using Transaction I will always use the testnet because it is set as default in NetworkConfig:

constructor() {
        this.ChainID = new ChainID("T");
(...)

It is probably something I don't understand, but for example, if I use 'dapp' library with the devnet config and try to use the browser extension to sign calls to SC, it will always use the testnet and always fail. 

For debugging I've done some hacks in erdjs like:
 

call({ func, args, value, gasLimit, receiver, chainId }: CallArguments): Transaction {
        args = args || [];
        value = value || Balance.Zero();
        
        let chainID: ChainID = new ChainID(chainId || 'T');

        let payload = TransactionPayload.contractCall()
            .setFunction(func)
            .setArgs(args)
            .build();

        let transaction = new Transaction({
            receiver: receiver ? receiver : this.getAddress(),
            value: value,
            gasLimit: gasLimit,
            data: payload,
            chainID,
        });

        transaction.onSigned.on(this.onCallSigned.bind(this));

        return transaction;
    }

Then I can call it like:

const contract = new SmartContract({
    address: new Address(sc_address_here),
  });

  contract.call({
    func: new ContractFunction('finction_name_here'),
    args: [args_here],
    gasLimit: new GasLimit(5000000),
    chainId: 'D', // This is my hack
  });

This way, it works as it should, but I guess there is something I am not aware of here. Maybe I shouldn't use SmartContract for calling my functions. Maybe there is another way to do it when integrating the `dapp` library?

Thanks.
 

Link to comment
Share on other sites

  • Elrond Team
17 hours ago, julian said:

Hi, I try to understand if I can use @elrondnetwork/erdjs (v8.0.0 but also v8.0.1-alpha.5) and SmartContract 'call' function, which uses Transaction under the hood. The problem is that I don't see a way to pass the ChainID where Transaction accepts that. So 'call' looks like this:

call({ func, args, value, gasLimit, receiver }: CallArguments): Transaction {
        args = args || [];
        value = value || Balance.Zero();

        let payload = TransactionPayload.contractCall()
            .setFunction(func)
            .setArgs(args)
            .build();

        let transaction = new Transaction({
            receiver: receiver ? receiver : this.getAddress(),
            value: value,
            gasLimit: gasLimit,
            data: payload
        });

        transaction.onSigned.on(this.onCallSigned.bind(this));

        return transaction;
    }

There is no option to pass the ChainID to Transaction. And it won't use proper chain id if I, for example, set up the 'dapp' with devnet config.

So if I won't pass the chainId using Transaction I will always use the testnet because it is set as default in NetworkConfig:

constructor() {
        this.ChainID = new ChainID("T");
(...)

It is probably something I don't understand, but for example, if I use 'dapp' library with the devnet config and try to use the browser extension to sign calls to SC, it will always use the testnet and always fail. 

For debugging I've done some hacks in erdjs like:
 

call({ func, args, value, gasLimit, receiver, chainId }: CallArguments): Transaction {
        args = args || [];
        value = value || Balance.Zero();
        
        let chainID: ChainID = new ChainID(chainId || 'T');

        let payload = TransactionPayload.contractCall()
            .setFunction(func)
            .setArgs(args)
            .build();

        let transaction = new Transaction({
            receiver: receiver ? receiver : this.getAddress(),
            value: value,
            gasLimit: gasLimit,
            data: payload,
            chainID,
        });

        transaction.onSigned.on(this.onCallSigned.bind(this));

        return transaction;
    }

Then I can call it like:

const contract = new SmartContract({
    address: new Address(sc_address_here),
  });

  contract.call({
    func: new ContractFunction('finction_name_here'),
    args: [args_here],
    gasLimit: new GasLimit(5000000),
    chainId: 'D', // This is my hack
  });

This way, it works as it should, but I guess there is something I am not aware of here. Maybe I shouldn't use SmartContract for calling my functions. Maybe there is another way to do it when integrating the `dapp` library?

Thanks.
 

can you check this thread first?

Unless we missed something, you should be able to use

let devnet = chooseProvider("elrond-devnet");

and then the chainID filled should be the one for devnet.

 

Link to comment
Share on other sites

Oh, I understand, so does it mean that we should have something like: 

let provider = chooseProvider(providerIdFromConfigHere);
await NetworkConfig.getDefault().sync(provider);

somewhere in the Dapp library? Because I am not sure how it should be integrated there.

There is something like:
 

React.useEffect(() => {
    if (chainId.valueOf() === "-1") {
      getNetworkConfig()
        .then((networkConfig) => {
          dispatch({
            type: "setChainId",
            chainId: networkConfig.ChainID,
          });
        })
        .catch((e) => {
          console.error("To do ", e);
        });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chainId.valueOf()]);

But from what I understand it will load the default NetworConfig so the ChainID will be the 'T'

Link to comment
Share on other sites

  • Elrond Team
20 minutes ago, julian said:

Oh, I understand, so does it mean that we should have something like: 

let provider = chooseProvider(providerIdFromConfigHere);
await NetworkConfig.getDefault().sync(provider);

somewhere in the Dapp library? Because I am not sure how it should be integrated there.

There is something like:
 

React.useEffect(() => {
    if (chainId.valueOf() === "-1") {
      getNetworkConfig()
        .then((networkConfig) => {
          dispatch({
            type: "setChainId",
            chainId: networkConfig.ChainID,
          });
        })
        .catch((e) => {
          console.error("To do ", e);
        });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chainId.valueOf()]);

But from what I understand it will load the default NetworConfig so the ChainID will be the 'T'

 

https://github.com/ElrondNetwork/elrond-sdk-erdjs/blob/bdec7b5fb1335dba3311d721681f35a16f1f4f5a/src/proxyProvider.ts#L102

if you pass to sync() the devnet provider (  chooseProvider("elrond-devnet") ) the network config will be taken through a GET request from the devnet so chainID should end up as 'D'

 

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...