Skip to content

Commit

Permalink
fix: set helper methods on contracts
Browse files Browse the repository at this point in the history
Set these up so we can call `deploy`, `at`, and `new` on contract
classes.
  • Loading branch information
Andre Medeiros authored and 0x-r4bbit committed Jan 27, 2020
1 parent c891c2d commit 46e4c4c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 37 deletions.
10 changes: 3 additions & 7 deletions dapps/tests/app/test/simple_storage_deploy_spec.js
Expand Up @@ -6,14 +6,10 @@ contract("SimpleStorage Deploy", function () {
let simpleStorageInstance;
before(function() {
return new Promise(async (resolve, reject) => {
const gas = await SimpleStorage.deploy({arguments: [150]}).estimateGas();

Utils.secureSend(web3, SimpleStorage.deploy({arguments: [150]}), {gas, from: web3.eth.defaultAccount}, true, function(err, receipt) {
if(err) {
return reject(err);
}
simpleStorageInstance = SimpleStorage;
simpleStorageInstance.options.address = receipt.contractAddress;
SimpleStorage.deploy([150]);
SimpleStorage.deployed().then(instance => {
simpleStorageInstance = instance;
resolve();
});
});
Expand Down
87 changes: 58 additions & 29 deletions packages/embarkjs/embarkjs/src/lib/blockchain.js
@@ -1,6 +1,7 @@
/* global ethereum */

import {reduce} from './async';
import { reduce } from './async';
import utils from './utils';

let Blockchain = {
Contract: Contract,
Expand Down Expand Up @@ -244,7 +245,7 @@ function Contract(options) {
this.abi = options.abi || options.abiDefinition;
this.address = options.address || options.deployedAddress;
this.gas = options.gas;
this.code = '0x' + options.code;
this.code = utils.hexPrefix(options.code);

this.blockchainConnector = Blockchain.blockchainConnector;

Expand Down Expand Up @@ -311,40 +312,50 @@ function Contract(options) {
}
});

// Assign helpers too
for(const method of ["deploy", "new", "at", "send", "deployed"]) {
// Make sure we don't override original methods here.
if (originalMethods.includes(method)) {
console.log(method + " is a reserved word and will not be aliased as a helper");
continue;
}

ContractClass[method] = Contract.prototype[method].bind(this);
}

this.contractClass = ContractClass;

return ContractClass;
}

Contract.prototype.deploy = function(args, _options) {
var self = this;
var contractParams;
var options = _options || {};

contractParams = args || [];
Contract.prototype.deploy = function(args, _options, _txOptions) {
const self = this;
const options = Object.assign({
arguments: args || [],
data: this.code
}, _options);

contractParams.push({
const txOptions = Object.assign({
from: this.blockchainConnector.getDefaultAccount(),
data: this.code,
gas: options.gas || 800000
gas: this.gas
}, _txOptions);

const contract = this.blockchainConnector.newContract({abi: this.abi});

this._deployPromise = new Promise((resolve, reject) => {
contract.deploy.apply(contract, [options]).send(txOptions).then(instance => {
resolve(new Contract({
abi: self.abi,
code: self.code,
address: instance.options.address
}));

// Delete the deploy promise as we don't need to track it anymore.
delete self._deployPromise;
}).catch(reject);
});


const contractObject = this.blockchainConnector.newContract({abi: this.abi});

return new Promise(function (resolve, reject) {
contractParams.push(function(err, transaction) {
if (err) {
reject(err);
} else if (transaction.address !== undefined) {
resolve(new Contract({
abi: self.abi,
code: self.code,
address: transaction.address
}));
}
});

contractObject["new"].apply(contractObject, contractParams);
});
return this._deployPromise;
};

Contract.prototype.new = Contract.prototype.deploy;
Expand All @@ -369,6 +380,24 @@ Contract.prototype.send = function(value, unit, _options) {
return this.blockchainConnector.send(options);
};

Contract.prototype.deployed = function() {
if (this.address === undefined && this._deployPromise === undefined) {
const err = Error("contract deployment hasn't happened yet");
return Promise.reject(err);
}

// This keeps the original deploy promise so we can fire it as soon as web3 tells us
// it's done.
if (this._deployPromise) {
return this._deployPromise;
}

// Already deployed, just resolve.
return Promise.resolve(this);
};

Blockchain.Contract = Contract;

class BlockchainConnectionError extends Error {
constructor(connectionErrors) {
super("Could not establish a connection to a node.");
Expand Down
6 changes: 6 additions & 0 deletions packages/embarkjs/embarkjs/src/lib/utils.js
Expand Up @@ -3,6 +3,12 @@
const Web3 = global.Web3 || require('web3');

let Utils = {
hexPrefix: function(str) {
if (!(str && str.match)) return;
if (str.match(/^0x/)) return str;

return `0x${str}`;
},
fromAscii: function(str) {
var _web3 = new Web3();
return _web3.utils ? _web3.utils.fromAscii(str) : _web3.fromAscii(str);
Expand Down
3 changes: 2 additions & 1 deletion packages/embarkjs/web3/src/index.js
Expand Up @@ -48,11 +48,12 @@ __embarkWeb3.newContract = function (options) {
};

__embarkWeb3.send = function () {
console.log('ARGUEMTNS', ...arguments);
return this.web3.eth.sendTransaction(...arguments);
};

__embarkWeb3.toWei = function () {
return this.web3.toWei(...arguments);
return this.web3.utils.toWei(...arguments);
};

__embarkWeb3.getNetworkId = function () {
Expand Down
1 change: 1 addition & 0 deletions packages/plugins/mocha-tests/src/lib/index.js
Expand Up @@ -131,6 +131,7 @@ class MochaTestRunner {
compiledContracts[contract.className] = {};
}
instance.options.from = accounts[0];
instance.options.code = contract.code;
instance.options.gas = GAS_LIMIT;
Object.setPrototypeOf(compiledContracts[contract.className], instance);
}
Expand Down

0 comments on commit 46e4c4c

Please sign in to comment.