Failed to deploy contract using typescript sdk

SDK version: fuels@0.74.0
nodejs version: v20.11.1
testnet version: beta-5
environment: MacOS 11.6.7

Steps to reproduce:

  1. Follow Quickstart Contract | Fuel Docs to build contract byte code & ABI.
  2. Use the following code to deploy contract:
    const factory = new ContractFactory(byteCode, abi, wallet);
    const { minGasPrice: gasPrice } = wallet.provider.getGasConfig();
    const contract = await factory.deployContract({ gasPrice });
    console.log(`${wallet.address.bech32Address} deployed contract ${contract.id}`);
    console.log(JSON.stringify(contract));

Expected behavior: Contract deployed successfully without error
Actual behavior:
const subscriptionStreamReader = response.body.pipeThrough(new FuelSubscriptionStream()).getReader();
^

TypeError: response.body.pipeThrough is not a function
at fuelGraphQLSubscriber (/Users/yuduan/Projects/fuel/node_modules/@fuel-ts/account/dist/index.js:1087:50)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async _Provider.sendTransaction (/Users/yuduan/Projects/fuel/node_modules/@fuel-ts/account/dist/index.js:3898:41)
at async ContractFactory.deployContract (/Users/yuduan/Projects/fuel/node_modules/@fuel-ts/contract/dist/index.js:166:5)

Node.js v20.11.1

Hi @yuduan0220, thanks for the report. There is a PR that will fix this error.

Also, please try using 0.73.0 as mentioned in the guide, and try again

@Dhaiwat10 I tried 0.73.0 and got the same error.

1 Like

Thanks @nedsalk is it gonna be included in 0.75.0?

@yuduan0220 You’re welcome! Yes, it’ll be included in that release. The PR for the release is here.

I downloaded 0.75.0 and got a different error now:

fuel/node_modules/@fuel-ts/account/dist/index.js:1065
this.stream = response.body.getReader();
TypeError: response.body.getReader is not a function

@yuduan0220 Where are you running your code, in nodejs (a server) or in Safari (a web app)? Also, could you please give us a repo with the problematic code?

Hey, I’m running it through cmd line with node version 16.
Another thing I found is that even exception was thrown, the contract was deployed and I could find it on the explorer.

The code is really simple, snippet below:


async function deploy(byteCode, abi, wallet) {
    const factory = new ContractFactory(byteCode, abi, wallet);
    const { minGasPrice: gasPrice } = wallet.provider.getGasConfig();
    const contract = await factory.deployContract({ gasPrice });
    console.log(`${wallet.address.bech32Address} deployed contract ${contract.id}`);
    console.log(JSON.stringify(contract));
    // interact with deployed contract

    await interact(contract.id, abi, wallet);
}

Could you please run it with node v18 or above? We officially support only v18 and v20.

On the note of successful deployment, it shouldn’t be possible for you to even deploy the app with node v16 because we’re using native fetch for all calls, which was only introduced in v17 under an experimental flag and stabilized in v18. I suspect you’ve got something going on with node-fetch being put in place of fetch, which allows you to send the contract deployment request but fails on response.body.getReader() because body.getReader doesn’t exist in node-fetch.

Brilliant, @nedsalk I’ve upgraded to node v18 and removed global fetch override. I’m able to deploy the contract, thanks a ton!

However I’m seeing a second issue, when trying to read value from the deployed contract.

async function interact(id, abi, wallet) {
    const contract = new Contract(id, abi, wallet);
    const { valueBefore } = await contract.functions.count().simulate();
    console.log({valueBefore});
}

I got the error: “RevertError: The script reverted with reason Unknown”

The contract I deployed is very simple:

contract;

storage {
    counter: u64 = 0,
}

abi Counter {
    #[storage(read, write)]
    fn increment(input: u64);

    #[storage(read)]
    fn count() -> u64;
}

impl Counter for Contract {
    #[storage(read)]
    fn count() -> u64 {
        return storage.counter.read()
    }

    #[storage(read, write)]
    fn increment(input: u64) {
        let incremented = storage.counter.read() + input;
        storage.counter.write(incremented);
    }
}

Great, we’re moving forward!

Related to the RevertError, I tried reproducing your error locally and it didn’t fail for me. Which forc version are you using to build your contract? It should be version 0.50.0.

Also, you’ve got a bug in { valueBefore }, it should be { value } because that’s the name of the return object’s property.

Hey thanks again for the hint, I checked I’m on 0.49.2.
When I run fuelup update, it says I already have the latest.
latest updated
updated components:

  • forc 0.49.2
  • forc-explore 0.28.1
  • forc-wallet 0.4.3
  • fuel-core 0.22.0
  • fuel-core-keygen 0.22.0

Hmm, I’m kinda stumped here. Perhaps you did something in-between that’s causing this issue because I’m able to interact with the equivalent contract normally, both with bytecodes generated with forc 0.49.2 and 0.50.0 on fuel-core 0.21.1 which is the beta-5 version of fuel-core.

Just to unblock you, given that you’re using the TS SDK, we do have a quickstart template that you can use. Could you please follow its instructions and let us know how it went?

Thanks again for your suggestion @nedsalk. I tried the below steps:

  1. Use a very simple contract, deploy it and read test_function through await contract.functions.test_function().simulate(); it works, I got value true in the response.
contract;

abi MyContract {
	fn test_function() -> bool;
}

impl MyContract for Contract {
	fn test_function() -> bool {
		true
	}
}
  1. Take the example contract from Quickstart Contract | Fuel Docs, deploy it then read the count through await contract.functions.count().simulate();, it doesn’t work and I got error “The script reverted with reason Unknown, cause: ScriptResultDecoderError: Execution of the script associated with contract xxx resulted in a non-zero exit code: 1”
contract;
 
storage {
    counter: u64 = 0,
}
 
abi Counter {
    #[storage(read, write)]
    fn increment();
 
    #[storage(read)]
    fn count() -> u64;
}
 
impl Counter for Contract {
    #[storage(read)]
    fn count() -> u64 {
        storage.counter.read()
    }
 
    #[storage(read, write)]
    fn increment() {
        let incremented = storage.counter.read() + 1;
        storage.counter.write(incremented);
    }
}

I also have this problem. Have you solved it

Nope, hasn’t heard back from the team yet. Keep me posted if you found something.