Skip to content

Commit

Permalink
Defer loading SolidityContract (#132)
Browse files Browse the repository at this point in the history
* Defer loading SolidityContract

Defer loading SolidityContract
Renamed getScheme to getContractWrapper
Bumped version number
Added forceReload to getWeb3

* removed foreceReload on getWeb3

* pull founders from json for migration

* removed console.log

* fix gas on forgeOrg

* network-specific founders json fles

* response to change requests

* migration documentation

* removed comments

* updates to genesisProtocol params

* added founders

* modified travis build -- migration requires build

* add all five founders to ganache Genesis migration

* sync up ganache with ganacheDb accounts

* try to fix travis build error

* another try at travis

* lint fix

* private keys to addresses

* back to Genesis for the DAO name
  • Loading branch information
dkent600 authored Mar 9, 2018
1 parent cd60285 commit 8e27e18
Show file tree
Hide file tree
Showing 28 changed files with 231 additions and 151 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ install:
- npm install
- nohup npm start test.ganache.run &
- npm start migrateContracts.fetchFromArc
- npm start build
- npm start migrateContracts

script:
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,21 +390,21 @@ Recall from [Categories of Arc Contracts](#categories-of-arc-contracts) that `ge

```javascript
import * as ArcJs from '@daostack/arc.js';
const upgradeScheme = await ArcJs.Contracts.getScheme("UpgradeScheme");
const upgradeScheme = await ArcJs.Contracts.getContractWrapper("UpgradeScheme");
```

#### At a specific address
```javascript
import * as ArcJs from '@daostack/arc.js';
const upgradeScheme = await ArcJs.Contracts.getScheme("UpgradeScheme", anAddress);
const upgradeScheme = await ArcJs.Contracts.getContractWrapper("UpgradeScheme", anAddress);
```

#### Via the DAO

The identical method is available on the DAO class:

```javascript
const upgradeScheme = await DAO.getScheme("UpgradeScheme");
const upgradeScheme = await DAO.getContractWrapper("UpgradeScheme");
```

### Obtain a wrapper using the wrapper's factory class
Expand Down Expand Up @@ -476,7 +476,8 @@ All of the scripts are defined in the package-scripts.js file. You have already
See also [Running Against a Ganache Database](#running-against-a-ganache-database), [Deploying to Other Testnets](#deploying-to-other-testnets) and [Run Lint and Tests](#run-lint-and-tests)

## Deploying to Other Testnets
The "network" environment variable defines which network arc.js understands you to be deploying to when you run the "migrateContracts" script. For safety it assumes a different HTTP port for each network. Can be "live" (the mainnet), "kovan" or "ganache". The default is "ganache".

Please refer [here](./docs/Migration.md) for instructions on migrating contracts to other test networks.

## Running Against a Ganache Database

Expand Down
10 changes: 10 additions & 0 deletions docs/Migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Deploying Contracts to a Specified Network

To deploy contracts to a specified network, follow these steps:

1) set the environment variable "network" to the name of the network ("ganache", "kovan", "live"). The default is "ganache". Truffle will use this to find the specified network settings in truffle.js.
2) if needed, set `network`, and `gasLimit_deployment` in /config/default.json and run `npm start build`
3) make sure that /migrations/founders.json has an entry for your network, with the appropriate founders
4) run `npm start migrateContracts`

Note: For safety, truffle.js specifies a different HTTP port for each network.
12 changes: 8 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ declare module "@daostack/arc.js" {
GlobalConstraintRegistrar: ArcContractInfo;
SchemeRegistrar: ArcContractInfo;
TokenCapGC: ArcContractInfo;
UController: ArcContractInfo;
UpgradeScheme: ArcContractInfo;
VestingScheme: ArcContractInfo;
VoteInOrganizationScheme: ArcContractInfo;
Expand Down Expand Up @@ -111,7 +110,7 @@ declare module "@daostack/arc.js" {
* @param contract - name of an Arc scheme, like "SchemeRegistrar"
* @param address - optional
*/
public static getScheme(contract: string, address?: string): Promise<ExtendTruffleScheme | undefined>;
public static getContractWrapper(contract: string, address?: string): Promise<ExtendTruffleScheme | undefined>;
}

/********************************
Expand All @@ -128,6 +127,11 @@ declare module "@daostack/arc.js" {
contractName: string
): any;

/**
* Returns the web3 object.
* When called for the first time, web3 is initialized from the Arc.js configuration.
* Throws an exception when web3 cannot be initialized.
*/
public static getWeb3(): Web3;

public static getValueFromLogs(
Expand Down Expand Up @@ -690,11 +694,11 @@ declare module "@daostack/arc.js" {
*/
public getGlobalConstraints(contractName?: string): Promise<Array<DaoGlobalConstraintInfo>>;
/**
* Returns an Arc.js scheme wrapper, or undefined if not found
* Returns an Arc.js contract wrapper, or undefined if not found
* @param contract - name of an Arc scheme, like "SchemeRegistrar"
* @param address - optional
*/
public getScheme(
public getContractWrapper(
contractName: string,
address?: string
): Promise<ExtendTruffleScheme | undefined>;
Expand Down
19 changes: 18 additions & 1 deletion lib/ContractWrapperFactory.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import { ExtendTruffleContract } from "ExtendTruffleContract";
import { Utils } from "./utils";

export default class ContractWrapperFactory<TContract extends ExtendTruffleContract> {

constructor(private solidityContract: any, private wrapper: new (solidityContract: any) => TContract) {
private solidityContract: any;

/**
* Instantiate a contract wrapper factory for the given wrapper class.
* @param solidityContract Name of the contract
* @param wrapper Class of the contract
*/
public constructor(private solidityContractName: string, private wrapper: new (solidityContract: any) => TContract) {
}

public async new(...rest: Array<any>): Promise<TContract> {
this.ensureSolidityContract();
return new this.wrapper(this.solidityContract).new(...rest);
}

public async at(address: string): Promise<TContract> {
this.ensureSolidityContract();
return new this.wrapper(this.solidityContract).at(address);
}

public async deployed(): Promise<TContract> {
this.ensureSolidityContract();
return new this.wrapper(this.solidityContract).deployed();
}

private ensureSolidityContract(): void {
if (!this.solidityContract) {
this.solidityContract = Utils.requireContract(this.solidityContractName);
}
}
}
12 changes: 4 additions & 8 deletions lib/ExtendTruffleContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import { Utils } from "./utils";
* Example of how to define a wrapper:
*
* import { ExtendTruffleContract } from "../ExtendTruffleContract";
* const SolidityContract = Utils.requireContract("AbsoluteVote");
* import ContractWrapperFactory from "../ContractWrapperFactory";
*
* export class AbsoluteVoteWrapper extends ExtendTruffleContract {
* [ wrapper properties and methods ]
* }
*
* const AbsoluteVote = new ContractWrapperFactory(SolidityContract, AbsoluteVoteWrapper);
* const AbsoluteVote = new ContractWrapperFactory("AbsoluteVote", AbsoluteVoteWrapper);
* export { AbsoluteVote };
*/
export abstract class ExtendTruffleContract {
Expand Down Expand Up @@ -150,8 +149,7 @@ export abstract class ExtendTruffleContract {
baseEvent.get((error: any, log: DecodedLogEntryEvent<TArgs> | Array<DecodedLogEntryEvent<TArgs>>) => {
if (!!error) {
log = [];
}
else if (!Array.isArray(log)) {
} else if (!Array.isArray(log)) {
log = [log];
}
callback(error, log);
Expand All @@ -162,8 +160,7 @@ export abstract class ExtendTruffleContract {
baseEvent.watch((error: any, log: DecodedLogEntryEvent<TArgs> | Array<DecodedLogEntryEvent<TArgs>>) => {
if (!!error) {
log = [];
}
else if (!Array.isArray(log)) {
} else if (!Array.isArray(log)) {
log = [log];
}
callback(error, log);
Expand All @@ -182,8 +179,7 @@ export abstract class ExtendTruffleContract {
(error: any, log: DecodedLogEntryEvent<TArgs> | Array<DecodedLogEntryEvent<TArgs>>): void => {
if (!!error) {
log = [];
}
else if (!Array.isArray(log)) {
} else if (!Array.isArray(log)) {
log = [log];
}
rootCallback(error, log);
Expand Down
17 changes: 8 additions & 9 deletions lib/avatarService.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import { Utils } from "./utils";
const UControllerContract = Utils.requireContract("UController");
const ControllerContract = Utils.requireContract("Controller");
const DAOToken = Utils.requireContract("DAOToken");
const Reputation = Utils.requireContract("Reputation");
const Avatar = Utils.requireContract("Avatar");
import { Contracts } from "./contracts.js";

/**
* Methods for querying information about an Avatar.
Expand Down Expand Up @@ -35,6 +29,7 @@ export class AvatarService {
*/
public async getAvatar(): Promise<any> {
if (!this.avatar) {
const Avatar = Utils.requireContract("Avatar");
this.avatar = await Avatar.at(this.avatarAddress);
}
return this.avatar;
Expand All @@ -59,13 +54,15 @@ export class AvatarService {
public async getController(): Promise<any> {

if (!this.controller) {
const contracts = await Contracts.getDeployedContracts();

const controllerAddress = await this.getControllerAddress();
/**
* TODO: check for previous and future versions of UController here
*/
this.isUController = contracts.allContracts.UController.address === controllerAddress;
const UControllerContract = Utils.requireContract("UController");
const ControllerContract = Utils.requireContract("Controller");
const uControllerAddress = (await UControllerContract.deployed()).address;

this.isUController = uControllerAddress === controllerAddress;
this.controller = this.isUController ?
await UControllerContract.at(controllerAddress) :
await ControllerContract.at(controllerAddress);
Expand All @@ -90,6 +87,7 @@ export class AvatarService {
public async getNativeReputation(): Promise<any> {
if (!this.nativeReputation) {
const reputationAddress = await this.getNativeReputationAddress();
const Reputation = Utils.requireContract("Reputation");
this.nativeReputation = await Reputation.at(reputationAddress);
}
return this.nativeReputation;
Expand All @@ -112,6 +110,7 @@ export class AvatarService {
public async getNativeToken(): Promise<any> {
if (!this.nativeToken) {
const tokenAddress = await this.getNativeTokenAddress();
const DAOToken = Utils.requireContract("DAOToken");
this.nativeToken = await DAOToken.at(tokenAddress);
}
return this.nativeToken;
Expand Down
45 changes: 17 additions & 28 deletions lib/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,26 @@ import { UpgradeScheme } from "./contracts/upgradescheme.js";
import { VestingScheme } from "./contracts/vestingscheme.js";
import { VoteInOrganizationScheme } from "./contracts/voteInOrganizationScheme.js";
import { ExtendTruffleContract } from "./ExtendTruffleContract";
import { Utils } from "./utils";

const UController = Utils.requireContract("UController");

/*******************************
* Arc contract information as contained in ArcDeployedContractNames
*/
export interface ArcContractInfo {
/**
* An uninitialized instance of ExtendTruffleContract,
* basically the class factory with static methods.
* ContractWrapperFactory that has static methods that return the contract wrapper.
*/
contract: any;
/**
* address of the instance deployed by Arc.
* Calling contract.at() (a static method on ExtendTruffleContract) will return a
* the properly initialized instance of ExtendTruffleContract.
* Calling contract.at() (a static method on ContractWrapperFactory) will return
* the fully hydrated instance of the wrapper class.
*/
address: string;
}

/**
* An object with property names being a contract key and property value as the corresponding ArcContractInfo.
* For all contracts deployed by Arc.js.
* An object with property names being a contract key and property value as the
* corresponding ArcContractInfo. Includes the set of contracts that have wrappers in Arc.js.
*/
export interface ArcDeployedContractNames {
AbsoluteVote: ArcContractInfo;
Expand All @@ -42,28 +38,30 @@ export interface ArcDeployedContractNames {
GlobalConstraintRegistrar: ArcContractInfo;
SchemeRegistrar: ArcContractInfo;
TokenCapGC: ArcContractInfo;
UController: ArcContractInfo;
UpgradeScheme: ArcContractInfo;
VestingScheme: ArcContractInfo;
VoteInOrganizationScheme: ArcContractInfo;
}

/**
* ArcDeployedContractNames, and those contracts organized by type.
* Call it.at(it.address) to get javascript wrapper
* Call it.at(it.address) to get contract wrapper
*/
export interface ArcDeployedContracts {
/**
* All wrapped contracts
*/
allContracts: ArcDeployedContractNames;
/**
* All deployed schemes
* All wrapped schemes
*/
schemes: Array<ArcContractInfo>;
/**
* All deployed voting machines
* All wrapped voting machines
*/
votingMachines: Array<ArcContractInfo>;
/**
* All deployed global constraints
* All wrapped global constraints
*/
globalConstraints: Array<ArcContractInfo>;
}
Expand All @@ -76,8 +74,7 @@ export class Contracts {

if (!Contracts.contracts) {
/**
* These are deployed contract instances represented by their respective Arc
* javascript wrappers (ExtendTruffleContract).
* These are the contract wrapper instances deployed by Arc.js.
*/
const absoluteVote = await AbsoluteVote.deployed();
const genesisProtocol = await GenesisProtocol.deployed();
Expand All @@ -87,14 +84,11 @@ export class Contracts {
const schemeRegistrar = await SchemeRegistrar.deployed();
const tokenCapGC = await TokenCapGC.deployed();
const upgradeScheme = await UpgradeScheme.deployed();
const uController = await UController.deployed();
const vestingScheme = await VestingScheme.deployed();
const voteInOrganizationScheme = await VoteInOrganizationScheme.deployed();

/**
* `contract` here is effectively the class wrapper factory.
* Calling contract.at() (a static method on the factory) will return a
* fully hydrated instance of ExtendTruffleContract.
* `contract` here is the ContractWrapperFactory
*/
const contracts = {
AbsoluteVote: {
Expand Down Expand Up @@ -125,10 +119,6 @@ export class Contracts {
address: tokenCapGC.contract.address,
contract: TokenCapGC,
},
UController: {
address: uController.address,
contract: UController,
},
UpgradeScheme: {
address: upgradeScheme.contract.address,
contract: UpgradeScheme,
Expand Down Expand Up @@ -167,12 +157,11 @@ export class Contracts {
}

/**
* Returns an Arc.js scheme wrapper, if wrapped, else raw Truffle contract,
* or undefined if not found
* @param contract - name of an Arc scheme, like "SchemeRegistrar"
* Returns an Arc.js contract wrapper or undefined if not found.
* @param contract - name of an Arc contract, like "SchemeRegistrar"
* @param address - optional
*/
public static async getScheme(contract: string, address?: string)
public static async getContractWrapper(contract: string, address?: string)
: Promise<ExtendTruffleContract | undefined> {
const contracts = await Contracts.getDeployedContracts();
const contractInfo = contracts.allContracts[contract];
Expand Down
6 changes: 2 additions & 4 deletions lib/contracts/absoluteVote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
import dopts = require("default-options");
import { Address, Hash, VoteConfig } from "../commonTypes";

import ContractWrapperFactory from "../ContractWrapperFactory";
import {
ArcTransactionDataResult,
ArcTransactionResult,
EventFetcherFactory,
ExtendTruffleContract
} from "../ExtendTruffleContract";
import { Utils } from "../utils";
const SolidityContract = Utils.requireContract("AbsoluteVote");
import ContractWrapperFactory from "../ContractWrapperFactory";
import { ExecuteProposalEventResult, NewProposalEventResult, VoteProposalEventResult } from "./commonEventInterfaces";

export class AbsoluteVoteWrapper extends ExtendTruffleContract {
Expand Down Expand Up @@ -80,7 +78,7 @@ export class AbsoluteVoteWrapper extends ExtendTruffleContract {
}
}

const AbsoluteVote = new ContractWrapperFactory(SolidityContract, AbsoluteVoteWrapper);
const AbsoluteVote = new ContractWrapperFactory("AbsoluteVote", AbsoluteVoteWrapper);
export { AbsoluteVote };

export interface CancelProposalEventResult {
Expand Down
Loading

0 comments on commit 8e27e18

Please sign in to comment.