How to deploy truffle contract to dev network when using inheritance? - ethereum

I have been attempting to deploy a contract using the Truffle framework, I have recently been testing these contracts on the development network.
My contract was very large and when I attempted to deploy it to a test net, I was instructed to split it up so that the contract wouldn't exceed the gas limit. Although, bearing in mind this contract did deploy onto the development network with the default gas limit.
So I took out parts of the contract and derived another contract from the base and added the deleted sections in there. I attempted to deploy it to the development network in order to test it again, I now get the error:
'Error: The contract code couldn't be stored, please check your gas amount.'
So the steps I took was to:
Change my gasLimit to 100,000,000 which didn't solve it
Check to see if my contract is 'abstract'
My understanding of this is that a contract is abstract if it or its
parent has any functions without an implementation. Mine don't.
I then deleted all of the code other than the constructor from the
derived contract and I still get this error
I deleted the file and the deployment worked with just my base contract as before, therefore the parent contract must not have any non-implemented functions AND it still doesn't work when I attempt to derive an empty contract from it (making sure nothing was abstract in the derived contract).
I then split my migration files up so that the migrations happen
separately, still no luck.
My parent contract is around 300 lines long so no point posting it all in here - I know some people will say 'it may just be too large' however, it deployed when it was 500 lines long on the dev network and now it is only 250 lines long with a deriving contract of 275 lines long, it does not deploy.
The error:
Running migration: 2_deploy_contracts.js
Replacing ERC20Token...
... 0xcae613274de1aa278e7ae5d1239f43445132a417d98765a4f227ea2439c9e4fc
ERC20Token: 0xeec918d74c746167564401103096d45bbd494b74
Replacing Crowdsale...
... 0x0ffc7291d84289c1391a81ed9f76d1e165285e3a3eadc065732aa288ea049b3a
Crowdsale: 0x0d8cc4b8d15d4c3ef1d70af0071376fb26b5669b
Saving successful migration to network...
... 0x7f351d76f61f7b801913f59b808688a2567b64933cdfdcf78bb18b0bf4e4ff69
Saving artifacts...
Running migration: 3_more_deployed_contracts.js
Deploying StagedSale...
... 0x216136bb24d317b140a247f10ec4d6791559739111a85932133cd4a66b12a1d9
Error encountered, bailing. Network state unknown. Review successful
transactions manually.
Error: The contract code couldn't be stored, please check your gas
amount.
at Object.callback
(/usr/local/lib/node_modules/truffle/build/cli.bundled.js:329221:46)
at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:39618:25
at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:331159:9
at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:175492:11
at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:314196:9
at XMLHttpRequest.request.onreadystatechange
(/usr/local/lib/node_modules/truffle/build/cli.bundled.js:329855:7)
My base contract is too large to post, and it deploys fine on its own meaning its not abstract.
My derived contract is:
pragma solidity ^0.4.16;
import "./SafeMath.sol";
import "./Crowdsale.sol";
contract StagedSale is Crowdsale {
using SafeMath for uint256;
/*
* Setup the contract and transfer ownership to appropriate beneficiary
*/
function StagedSale
(
uint256 _stage1Duration,
uint256 _stage2Duration
) public {
uint256 stage1duration = _stage1Duration.mul(1 minutes);
uint256 stage2duration = _stage2Duration.mul(1 minutes);
}
My migration file for the derived contract:
var StagedSale = artifacts.require("./StagedSale.sol");
module.exports = function(deployer) {
const stage1Duration = 1;
const stage2Duration = 1;
deployer.deploy(StagedSale, stage1Duration, stage2Duration);
};
I have posted this question here as I fear this may be a common issue with Truffle deployment.
To conclude, I don't believe this has anything to do with the actual gas limits and is instead, failing for some unknown reason and printing this error message anyway.

I've found a fix to this, basically if you are inheriting from a base contract, you must deploy the base contract within the inherited contracts constructor like so:
OLD VERSION:
Simply deployed the base, then deployed the inheriting contract with a reference to 'is Crowdsale' in class name
deployer.deploy(ERC20Token, initialAmount, tokenName, decimalUnits,tokenSymbol).then(function() {
return deployer.deploy(Crowdsale, softCap, hardCap, etherCostOfEachToken, sendFundsTo, toChecksumAddress(ERC20Token.address), durationInMinutes);
});
deployer.deploy(FinalizableSale);
NEW VERSION
Only deploy the inheriting contract and create a new instance of base within that constructor
deployer.deploy(ERC20Token, initialAmount, tokenName, decimalUnits,tokenSymbol).then(function() {
return deployer.deploy(Finalizable, softCap, hardCap, etherCostOfEachToken, sendFundsTo, toChecksumAddress(ERC20Token.address), durationInMinutes);
});
FINALIZABLE CONSTRUCTOR:
function FinalizableSale(uint256 _fundingGoalInEthers, uint256 _fundingLimitInEthers, uint256 _etherCostOfEachToken, address _sendFundsTo, address _tokenAddress, uint256 _durationInMinutes)
Crowdsale(_fundingGoalInEthers, _fundingLimitInEthers, _etherCostOfEachToken, _sendFundsTo, _tokenAddress, _durationInMinutes)
{
//do something
}
NOTE: That the base contract is initialised BEFORE the opening brackets to the constructor function.
I no longer get the 'out of gas' error and my contract runs as before.

Related

Why would create2 revert?

I'm debugging a reverted transaction on Polygon and this is all the information I have: https://mumbai.polygonscan.com/tx/0xfa86dc4957e3a3da9298b7672b11a20ebe921854fa494dc073920c067c1e693f#internal
If I'm reading it correctly, it seems to be saying that a CREATE2 reverted. But what are some reasons why a CREATE2 can revert? I'm aware that it would revert if something already existed at the address, but this isn't the case here, as you can see from here: https://mumbai.polygonscan.com/address/0x6bb03ca906c0372f384b845bd5ce9ca4327ffbe6
The linked transaction makes a message call (aka internal transaction) to contract deployed at 0x1079b7398b6efd9845c4db079e6fac8d21cf67b3.
This 0x1079b7... contract then tries to deploy a new contract on address 0x6bb03ca906c0372f384b845bd5ce9ca4327ffbe6, you can see the bytecode of the new contract for example in the Tenderly debugger.
As far as I'm aware, create2 can revert for 3 reasons:
Not enough gas left to perform the deployment
Not an issue in this case. Acording to the debugger there was ~9M gas units left and the deployment would take only ~1M gas units.
Deploying contract to address where another contract instance is already deployed.
Because you can predetermine the contract address with create2, this can happen. However not in this case either, the 0x6bb03c... address is empty, there's no contract deployed.
So we're left with uncaught exception during executing the constructor.
pragma solidity ^0.8;
contract MyContract {
constructor() {
require(false);
}
}
A code like this fails the deployment and effectively causes the create2 code to revert.
Unfortunately, without the new contract source code, it's hard to tell what exactly is the cause of constructor revert. Whether it's unexpected length or input params to the constructor, logical error, trying to make a call to non-existing contract, or anything else.
It turns out that I'm misreading Polygonscan and that just because there's a red mark next to an internal transaction doesn't mean that it's the internal transaction itself that reverted; it means that the whole transaction reverted. Anyways, using the Tenderly debugger helped me identity the real bug.

Deployed contract different from local packaged contracts (openzeppelin and GSN)

This is directly related to my previous issue, although now I have more specifics and therefore I'm writing a new question!
I was handed a project, and I've installed all the dependencies with npm ci, which should coincide exactly with what the package-lock.json says.
Although, I get compiling errors with an OpenZeppelin contract and a GSN contract.
When looking at the deployed contract, I can see that the code indeed is different and coincides with what the compiler is complaining about;
OpenZeppelin/Context.sol (Deployed)
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return payable(msg.sender);
}
...
OpenZeppelin/Context.sol (local)
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
...
Difference> payable(msg.sender), which is what my compiler is complaining about in two places (once in GSN contract BaseRelayRecipient too).
So... as the versions for both OpenZeppelin and GSN are correct according to my node_modules and the package.json;
"#opengsn/contracts": "^2.2.2",
"#openzeppelin/contracts": "^4.1.0",
Is it the compiler which is supposed to... fix the payable part...? Or... what am I missing, assuming my local code is indeed what was deployed (which I'm 99% of).

Solidity - Add Total Supply

I'm learning solidity on remix
I'm also referencing this open source api for token creation.
Right here they provide a _totalSupply() function that I'd like to wire to my smart contract so it shows the total amount of tokens why I deploy it.
What am doing wrong here?
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
contract Foobar is ERC20 {
constructor(uint256 initialSupply) public ERC20("Foobar", "FOO") {
_mint(msg.sender, initialSupply);
// add totalSupply here
_totalSupply(uint256 5000000000000000000000000000000000000000);
}
}
OpenZeppelin ERC20 _totalSupply is a private property, which means you can't access it from a derived contract (in your case Foobar).
GitHub link to the property definition
Solidity docs on visibility modifiers
Also your syntax is incorrect. If the property were at least internal, you could set its value as
_totalSupply = 5000000000000000000000000000000000000000;
or in a more readable way
_totalSupply = 5 * 1e39;
If you want to change its visibility, you'll need to copy the (parent) ERC20 contract to your IDE and change the import statement to reflect the new (local) location. Then you'll be able to update the property visibility in your local copy of the contract.
Mind that the OpenZeppelin ERC20 contains relative import paths (e.g. import "./IERC20.sol";). You'll need to rewrite these in your local copy as well, so that they point back to the GitHub locations. Otherwise, the compiler would be trying to import non-existing local files.
OpenZeppelin contracts automatically update totalSupply when you mint or burn tokens. They also automatically expose this as a variable you can read. You do not need, and you should not and you cannot set totalSupply by hand, because then the number of distributed tokens would not match the total supply.

Fail to Deploy Simple Solidity Contract via Remix

Why does Remix fail to deploy the simple contract (simplified from the Mastering Ethereum book https://github.com/ethereumbook/ethereumbook/blob/develop/code/Solidity/Faucet2.sol )? --
pragma solidity ^0.4.19;
contract Faucet {
function withdraw(uint withdraw_amount) public {
require(withdraw_amount <= 100000000000000000);
msg.sender.transfer(withdraw_amount);
}
function () external payable {}
}
No matter how I raise gasLimit and/or gasPrice
Your code is fine (I have also tried it myself). From what I see above you are also sending a value along with the deploy. Since you have not defined a constructor yourself the default one is being called which is not payable. If you want to send ether when you deploy the contract you should also define a payable constructor.

Creating Ethereum Contracts (go ethereum)

Trying to follow the wiki example for go ethereum to create a basic contract:
https://github.com/ethereum/go-ethereum/wiki/Contracts-and-Transactions
Everything seems to work until I get down until the last line:
source = "contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"
contract = eth.compile.solidity(source).test
primaryAddress = eth.accounts[0]
# **Problems start here **
MyContract = eth.contract(abi);
contact = MyContract.new(arg1, arg2, ...,{from: primaryAddress, data: evmCode})
What is the "abi" argument for the eth.contract method? Also, what would I put in the "evmCode" argument? In this particular example, seems like I would put in an integer for "arg1" but not sure what the full example should look like.
The ABI is the interface that your contract exposes. "evmCode" is the Ethereum byte code for your contract.
To work around your problem, go to https://chriseth.github.io/browser-solidity/ and plug your Solidity in. The Bytecode field on the right will give you the value for "evmCode" and Interface will give you the ABI.
You can also copy the snippet from "Web3 deploy" and paste it in your code to deploy your contract.
ABI is basically which is the public facing interface that shows what methods are available to call.
The simplest way to get the abi would be to use https://remix.ethereum.org . just paste in your code and in Contract tab At the bottom of the column you’ll find a link that says Contract details which is basically the ABI json
Conversely you could also use the contracts.Introduction.interface api of web3 to get the abi.
ABI is representation of smart contract that can be read using java script .To read the data from a deployed contract account in etherum , you'll need some extra details like abi.
Steps to get abi of any smart contract:
1.Each contract has contract hash address like this:0x0D8775F648430679A709E98d2b0Cb6250d2887EF
2.Go to etherscan.io and search your contract address hash in search bar and you will get contract.
3.In contract go to code and there you can find this abi
can check this link to find abi
You could try using tools like Etherlime shape or Truffle boxes to have a whole sample project with contract, tests, and usage into the js. From here you could start moving forward.
ABI is Application Binary Interface. A contract when compiled by solidity compiler returns an object with different methods. ABI and Bytecode are basically used methods. ABI is used to interact with your contracts and frontend (if using node) and bytecode is used for deploying to Rinkeby (or any Ethereum network).
For example:
Contract is:
pragma solidity ^0.4.17;
contract Inbox
{
string public message;
function Inbox(string initialMessage) public{
message = initialMessage;
}
function setMessage(string newMessage) public{
message = newMessage;
}
}
Its ABI is:
interface:
[{
"constant":false,"inputs":[{
"name":"newMessage","type":"string"
}]
,"name":"setMessage","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"
}
,{
"constant":true,"inputs":[],"name":"message","outputs":[{
"name":"","type":"string"
}]
,"payable":false,"stateMutability":"view","type":"function"
}
,{
"inputs":[{
"name":"initialMessage","type":"string"
}]
,"payable":false,"stateMutability":"nonpayable","type":"constructor"
}]
This is returned after compiling the contract. You can see it consists of methods used in our contract.