The Truffle test encounters an issue: "Error: Trying to execute a transaction that calls a contract function, but the recipient address ___ is not a contract address."

Every time I run truffle test in the terminal, I encounter the following error message:

Error: Attempting to run a transaction which calls a contract function, but the recipient address 0x3ad2c00512808bd7fafa6dce844a583621f3df87 is not a contract address
. I find this puzzling because my build folder appears to be normal. When I execute truffle migrate --reset, the address in the terminal matches the address in the build file. The migration process works fine. However, each time I run the truffle test, the recipient address seems to change. I'm unsure of what steps to take next and would appreciate any assistance.

It is worth mentioning that this error occurs only when I implement the following code: selfdestruct(admin);. In this scenario, the admin is equal to msg.sender, which refers to the initial account in the ganache setup. I'm at a loss as to what might be causing this issue.

I have been following this tutorial video. While I successfully completed all the previous tutorials by this individual, I am now stuck at minute 15:11, where he carries out the final test without any issues. Unfortunately, for me, it results in the error mentioned above.

If anyone has a solution, I would greatly appreciate the assistance.

Here is my test (javascript):

var CinoCoin = artifacts.require("./CinoCoin.sol");
var CinoCoinSale = artifacts.require("./CinoCoinSale.sol");

// Contract testing code continues below...

And here is the contract code (solidity):

pragma solidity ^0.4.23;

import "./CinoCoin.sol";

contract CinoCoinSale {
  // Contract implementation goes here...
}

When I comment out the selfdestruct(admin); line, the tests pass without any issues. This indicates that the problem might be related to that particular line. Your help is much appreciated. Thank you.

Answer №1

Great job on resolving the error swiftly. Upon reviewing your code, I found that the test file is quite intricate to navigate due to the extensive promise chains. I took the liberty to refactor the file using async/await, which should make it easier to manage and debug in the future.

Furthermore, I observed that you are manually verifying emitted events and reverts by inspecting the logs and catching the revert exception. To streamline this process, I have incorporated a library that simplifies these tasks. I have included the necessary code for integrating this library as well.

To install the library via npm, use the following command:

npm install truffle-assertions

Following this installation, your new test code should function correctly. I trust this modification will prove beneficial to your Dapp development endeavors. Best of luck!

const CinoCoin = artifacts.require("CinoCoin");
const CinoCoinSale = artifacts.require("CinoCoinSale");
const truffleAssert = require("truffle-assertions");

contract('CinoCoinSale', function(accounts) {
  let tokenInstance;
  let tokenSaleInstance;
  let admin = accounts[0];
  let buyer = accounts[1];
  let tokenPrice = 1000000000000000; // in wei 0.01 ether
  let tokensAvailable = 750000;

  it('initializes the contract with the correct values', async function() {
    tokenInstance = await CinoCoin.deployed();
    tokenSaleInstance = await CinoCoinSale.deployed();

    assert.notEqual(tokenSaleInstance.address, 0x0, 'has contract address');
    assert.notEqual(await tokenSaleInstance.tokenContract(), 0x0, 'has token contract address');
    assert.equal(await tokenSaleInstance.tokenPrice(), tokenPrice, 'token price is correct');
    assert.equal(await tokenSaleInstance.admin(), admin, 'admin is correct');
  });

  it('facilitates token buying', async function() {
    tokenInstance = await CinoCoin.deployed();
    tokenSaleInstance = await CinoCoinSale.deployed();
    await tokenInstance.transfer(tokenSaleInstance.address, tokensAvailable, { from: admin });

    const numberOfTokens = 10;
    const receipt = await tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: numberOfTokens * tokenPrice });

    truffleAssert.eventEmitted(receipt, 'Sell', (ev) => {
      return ev._buyer === buyer && ev._amount.toNumber() === numberOfTokens;
    });

    const tokensSold = await tokenSaleInstance.tokensSold();
    assert.equal(tokensSold.toNumber(), numberOfTokens, 'increments the number of tokens sold');

    const buyerBalance = await tokenInstance.balanceOf(tokenSaleInstance.address);
    assert.equal(buyerBalance.toNumber(), numberOfTokens);

    const tokenSaleBalance = await tokenInstance.balanceOf(tokenSaleInstance.address);
    assert.equal(tokenSaleBalance.toNumber(), tokensAvailable - numberOfTokens);

    truffleAssert.reverts(
      tokenSaleInstance.buyTokens(numberOfTokens, { from: buyer, value: 1 }),
      null,
      'msg.value must equal number of tokens in wei'
    );

    truffleAssert.reverts(
      tokenSaleInstance.buyTokens(800000, { from: buyer, value: numberOfTokens * tokenPrice }),
      null,
      'connot purchase more tokens than available'
    );
  });

  it('ends token sale', async function () {
    tokenInstance = await CinoCoin.deployed();
    tokenSaleInstance = await CinoCoinSale.deployed();

    truffleAssert.reverts(tokenSaleInstance.endSale({ from: buyer }), null, 'must be admin to end sale');

    await tokenSaleInstance.endSale({ from: admin });

    const adminBalance = await tokenInstance.balanceOf(admin);
    assert.equal(adminBalance.toNumber(), 999990, 'returns all unsold cino coins to admin');

    const tokenPrice = await tokenSaleInstance.tokenPrice();
    assert.equal(tokenPrice.toNumber(), 0, 'token price was reset');
  });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adjust the map automatically as the cursor approaches the map's edge in Google Maps API V3

My latest project involved creating a selection tool using the Rectangle shape tool. With this tool, users can easily select markers by drawing a rectangle over them and releasing their mouse to erase the selection (similar to selecting items on a desktop ...

How can you incorporate TypeScript's dictionary type within a Mongoose schema?

When using TypeScript, the dictionary type format is: { [key: string]: string; } However, when I try to define a custom schema in mongoose, it doesn't work as expected. const users = new Schema({ [key: string]: String, }); I also attempted t ...

Updating the image source URL dynamically inside a division within a script using JavaScript

I'm attempting to insert a dynamic URL within an img src tag. Below is my HTML and Script code. When a tab is clicked, a GET HTTP Method is called, which responds with an image URL. I want to use this image URL in the img src field. HTML Code ...

What is the process for incorporating a custom attribute into an element with Vue directives?

One of the challenges I'm facing is dealing with a custom attribute called my-custom-attribute. This attribute contains the ID for the element that needs to have the attribute added or removed based on a boolean value. Although I've implemented ...

LeadFoot's intern framework encountered difficulty locating an element

I am currently in the process of writing functional test cases using the leadfoot intern framework. The specific test case I am working on involves entering text into a form field and clicking a button that triggers the opening of a bootstrap modal. My goa ...

Verify the entered information in the input field and showcase it in the display box after pressing the ENTER key

I need to display selected values of a tree structure in a show box on the other side of the page using code. However, I also need to include HTML input boxes in some lines of the tree structure so that users can input data. The challenge is getting the in ...

Angular Promises - Going from the triumph to the disappointment callback?

It seems like I might be pushing the boundaries of what Promises were intended for, but nonetheless, here is what I am attempting to do: $http.get('/api/endpoint/PlanA.json').then( function success( response ) { if ( response.data.is ...

What are some methods to prevent cookies from being overridden?

Just beginning my journey in web development. Currently utilizing asp.net Web API and Angular with token authentication. Every time a user logs in, I set the token in a cookie and send it with each request. Everything has been running smoothly so far, bu ...

Canvg | Is there a way to customize canvas elements while converting from SVG?

Recently, I encountered an issue with styling SVG graphics dynamically generated from data. The SVG graphic appears like this: https://i.sstatic.net/xvIpE.png To address the problem, I turned to Canvg in hopes of converting the SVG into an image or PDF us ...

Show spinner until the web page finishes loading completely

Could anyone guide me on how to display Ring.html for a brief moment until About.html finishes loading completely? I need the Ring.html page to vanish once About.html is fully loaded. As a beginner in web development, I would greatly appreciate your assist ...

Dealing with ReactJs Unhandled Promise Rejection: SyntaxError - Here's the Solution

Struggling to use the Fetch API in ReactJS to retrieve a list of movies. Encountering an issue, can anyone offer assistance? fetch("https://reactnative.dev/movies.json", { mode: "no-cors", // 'cors' by default }) ...

How to use jQuery to delete the final table in an entire HTML document

This situation is really frustrating: When I make a jQuery Ajax call, the success callback returns an entire HTML page. The returned page looks like this: <html> <head> <title>Title</title> <body> <table></table> ...

Unusual numerical output observed when utilizing fmt.Println in the Golang programming language

Just recently started using Golang and came across an unusual issue with fmt that I have never experienced before. Whenever I print a string, at the end of the output, it displays what seems to be the length of each substring, which doesn't seem to al ...

jq: filter out arrays that include element B and include element A

My information consists of JSON arrays. Each array includes elements with both name and ID keys: [ { "name": "first_source", "id": "abcdef" }, { "name": "second_source", "id": "ghijkl" }, { "name": "third_source", "id": " ...

Refresh a div with Ajax once all data has been fully loaded

I am currently using an ajax refresh div function that reloads a specific div every 10 seconds. Occasionally, the div loads before receiving data from mysql. Is there a way to modify it so that it waits 2 seconds after reloading the div? <script type ...

Ways to resolve the issue of the experimental syntax 'jsx' not being enabled

I encountered an issue while trying to implement react-fancybox and received an error. https://i.sstatic.net/vgFha.png To resolve the error, I executed the following commands: npm install --save-dev @babel/preset-react, npm install --save-dev @babel/plugi ...

MDL Tab loading Problem

When visiting my website at this link, which is powered by MDL from Google, there is a troublesome issue that occurs. The #harule tab briefly appears before disappearing. This tab should actually be hidden on the page until a user clicks on the harule tab ...

Getting a string representation of an object from JSON in Swift

My Swift WebSocket connection is returning JSON data structured like this: { "identifier": "{\"channel\":\"SomeChannel\"}", "message": { "resource": { ...

Alter the style type of a Next.js element dynamically

I am currently working on dynamically changing the color of an element based on the result of a function //Sample function if ("123".includes("5")) { color = "boldOrange" } else { let color = "boldGreen" } Within my CSS, I have two clas ...

Is it necessary for JavaScript functions to be stored in a separate file in order to be invoked?

Here is the scenario that unfolded: Within a .php file, I had the following form: <form action="/flash_card/scripts/create_user_gate.php" onsubmit="return validateForm()" method="post"> <table align="center"> ...