3

What is a good way to solve my deployment issue: (furtherance of issue: truffle testing problem, migration successful, testing runs out of gas with addition of testing file)

When i add the TestProcessApplicants.sol file i run out of gas. I suspect this is also true, due to the instantiation of local instances to test some modifiers in the solidity tests.

Modules Remix TransactionCost
CredentialOrgFactory 2209646
CredentialFactory 1934056
SafeMath32 74748
ApplicantFactory 2432336
ProcessApplicants 1937776
Total 8588562

I suspect a 3_deploy_contracts.js file will be needed. I need to be able to set reference addresses like in below deploy, but I need to be able to see previous (2_deploy_contracts.js) instances. how would i go about doing that? Or is there a better approach? or am i just 'doing it wrong'. lol.

here is 2_deploy_contracts.js

var SafeMath32 = artifacts.require("./SafeMath32.sol");
var CredentialOrgFactory = artifacts.require("CredentialOrgFactory");  
var CredentialFactory = artifacts.require("CredentialFactory");        
var ApplicantFactory = artifacts.require("ApplicantFactory");          
var ProcessApplicants = artifacts.require("ProcessApplicants");

module.exports = async function(deployer, accounts) {
    let safeMathInst, aInst, bInst, cInst, dInst;

    await Promise.all([
    deployer.deploy(SafeMath32),
    deployer.deploy(CredentialOrgFactory),
    deployer.deploy(CredentialFactory),
    deployer.deploy(ApplicantFactory),
    deployer.deploy(ProcessApplicants),
    deployer.link(SafeMath32, [CredentialOrgFactory,CredentialFactory,ApplicantFactory])
]);  

instances = await Promise.all([
    SafeMath32.deployed(),
    CredentialOrgFactory.deployed(),
    CredentialFactory.deployed(),
    ApplicantFactory.deployed(),
    ProcessApplicants.deployed(),
])

aInst = instances[1];
bInst = instances[2];
cInst = instances[3];
dInst = instances[4];

results = await Promise.all([  
    // Set Address of bInst so it can point at aInst
    console.log("setAddress CredentialFactory: for CredentialOrgFactory"),
    bInst.setAddress(aInst.address),
    // Set Address of cInst so it can point at aInst
    cInst.setAddress(aInst.address),
    // Set Address of dInst so it can point at aInst, bInst, and cInst
    dInst.setAddress(aInst.address, bInst.address, cInst.address)
    ]);

};

1 Answer 1

1

An alternative approach to Truffle's migration:

Add web3 v1 to your package.json file:

  "devDependencies": {
    "web3": "1.0.0-beta.34",
    ...
  }

Create a helper file util.js:

let fs = require("fs");
let Web3 = require("web3");

let web3 = new Web3(NODE_ADDRESS);

async function send(transaction, gasMul = 1, gasAdd = 0) {
    let gas = await transaction.estimateGas({from: PUBLIC_KEY});
    let options = {
        to  : transaction._parent._address,
        data: transaction.encodeABI(),
        gas : gas * gasMul + gasAdd
    };
    let signedTransaction = await web3.eth.accounts.signTransaction(options, PRIVATE_KEY);
    return await web3.eth.sendSignedTransaction(signedTransaction.rawTransaction);
}

async function deploy(contractName, contractArgs) {
    let abi = fs.readFileSync(contractName + ".abi").toString();
    let bin = fs.readFileSync(contractName + ".bin").toString();
    let contract = new web3.eth.Contract(JSON.parse(abi));
    let handle = await send(contract.deploy({data: "0x" + bin, arguments: contractArgs}));
    console.log(`${contractName} contract deployed at address ${handle.contractAddress}`);
    return new web3.eth.Contract(JSON.parse(abi), handle.contractAddress);
}

function deployed(contractName, contractAddr) {
    let abi = fs.readFileSync(contractName + ".abi").toString();
    return new web3.eth.Contract(JSON.parse(abi), contractAddr);
}

In your deployment scripts, use it as follows:

File 2_deploy_contracts.js:

let util = require("./util.js");
...
async function run() {
    let myContract = await util.deploy("MyContract", [arg1, arg2, arg3]);
    // Do asynchronous stuff with myContract...
}
...
run();

File 3_deploy_contracts.js:

let util = require("./util.js");
...
async function run() {
    let myContract = util.deployed("MyContract");
    // Do asynchronous stuff with myContract...
}
...
run();

Execute these deployment scripts with NodeJS:

node 2_deploy_contracts.js
node 3_deploy_contracts.js

I would recommend passing your system-configuration from command line, i.e:

In each one of your deployment scripts, add this:

let NODE_ADDRESS = process.argv[2];
let PUBLIC_KEY   = process.argv[3];
let PRIVATE_KEY  = process.argv[4];

And then pass these values to the util module.

3
  • I will definitely will look at it further. I'm doing this for a class and i have to use truffle migrate.
    – shaddow
    Commented Aug 20, 2018 at 8:53
  • 1
    @shaddow: I've found Truffle's "migration syntax" to be very non-intuitive to use. Commented Aug 20, 2018 at 9:22
  • 1
    the more i read this the more I like it. I have some ideas to try now using the migration on how to get the data into it. I think i can easily do it in staging the pushes, but i'm really looking for a 'push button' and be done approach, that is easy to read, easy to implement, and share.
    – shaddow
    Commented Aug 27, 2018 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.