DEVELOPMENT OF THIS PACKAGE HAS MOVED TO: https://github.com/daostack/alchemy-monorepo/tree/dev/packages/migration
A repo for handling the migration of DAOstack contracts and DAOs. This repo is packaged both as an npm package and a Docker image that exposes a pre-migrated ganache instance and other utilities related to migration.
Migration is separated into two phases:
- Base migration - of universal contracts from the
@daostack/arcpackage. - DAO migration - of an example DAO.
Both the npm package and the docker image are versioned according to the @daostack/arc package and the migration version. Example: @daostack/arc@<arc version> -> npm: @daostack/ganache@<arcversion>-v<migration version> and dockerhub: daostack/ganache:X.Y.Z-v<migration version>
npm install --save @daostack/migration
const DAOstackMigration = require('@daostack/migration'); // ganache-core object with already migrated contracts // options are as specified in https://github.com/trufflesuite/ganache-cli#library DAOstackMigration.Ganache.server(..); DAOstackMigration.Ganache.provider(..); // choose the network to get addressed for. Either private (ganache), kovan, rinkeby, mainnet. let network = 'private' // migration result object for ganache DAOstackMigration.migration(network); const options = { // arc version arcVersion: '0.0.1-rc.32', // web3 provider url provider: 'http://localhost:8545', // gas price in GWei. If not specified, will use an automatically suggested price. gasPrice: 3.4, // suppress console output quiet: true, // disable confirmation messages disable-confs: true, // force deploy everything force: true, // delete previous deployment state and starts with clean state restart: false, // filepath to output the migration results output: 'migration.json', // private key of the account used in migration (overrides the 'mnemonic' option) privateKey: '0x123...', // mnemonic used to generate the private key of the account used in migration mnemonic: 'one two three ...', // migration parameters params: { default: { // migration params as defined in the "Migration parameters" section below }, private: { // override defaults on private network }, kovan: { // override defaults on kovan }, }, }; // migrate base contracts const migrationBaseResult = await DAOstackMigration.migrateBase(options); migrationBaseResult.base.GenesisProtocol // migrated genesis protocol address // migrate an example DAO (requires an existing `output` file with a base migration) const migrationDAOResult = await DAOstackMigration.migrateDAO(options); migrationDAOResult.dao.Avatar // DAO avatar address // migrate an demo test scenario (requires an existing `output` file with a base migration) const migrationDemoResult = await DAOstackMigration.migrateDemoTest(options); migrationDemoResult.test.Avatar // Test DAO avatar address // migrate base, example DAO and demo test contracts const migrationResult = await DAOstackMigration.migrate(options); // migrate // run the cli DAOstackMigration.cli()npm install --global @daostack/migration
Note: if you encounter an issue which contains this error message EACCES: permission denied, mkdir please follow this guide and try again
Usage:
Migrate base contracts and an example DAO Commands: daostack-migrate Migrate base contracts and an example DAO [default] daostack-migrate base Migrate base contracts daostack-migrate dao Migrate an example DAO daostack-migrate completion generate bash completion script Options: --version Show version number [boolean] --arc-version, -a Use a specific Arc package version [string] [default: latest supported version] --provider, -p web3 provider url [string] [default: "http://localhost:8545"] --gas-price, -g gas price in GWei. If not specified, will use an automatically suggested price. [number] --quiet, -q suppress console output [boolean] [default: false] --force, -f disable confirmation messages [boolean] [default: false] --restart, -t delete previous deployment state and starts with clean state restart [boolean] [default: false] --output, -o filepath to output the migration results [string] [default: "migration.json"] --params, -i path to the file containing the migration parameters [string] [default: "migration-params.json"] --private-key, -s private key of the account used in migration (cannot be used with the 'mnemonic' option) [string] [default: "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"] --mnemonic, -m mnemonic used to generate the private key of the account used in migration (cannot be used with the 'private-key' option) [string] --help Show help [boolean] -
Make sure you have Node.js and NPM installed and updated to a version later than 10.15.3 and 6.0.0 respectively. You can find instructions for installation here, and then verify your version by opening your CMD/ Terminal and type:
node -vand thennpm -v. -
In your terminal, use this command to install the DAOstack migration CLI:
npm install --global @daostack/migration. -
Create a new
your-new-dao-params.jsonfile, you can also use the samemigration-params.jsonfrom the DAOstack migratio GitHub repo. -
Customize
your-new-dao-params.jsonby setting up the DAO name, token, founders, schemes etc. To learn more about the customization options for the parameters please see the Migration parameters section below. -
Obtain a URL of an Ethereum node connected to your desired network. You can also use Infura for that.
-
Get some ether in your Ethereum account to pay for the mining fee of deploying the DAO. Make sure you have the private key for the account.
-
In the terminal window, use this command to deploy your DAO:
daostack-migrate dao --params <YOUR_PARAMS_FILE_LOCATION> --gasPrice <YOUR_DESIRED_VALUE> --provider <YOUR_ETHERUM_NODE> --private-key <YOUR_PRIVATE_KEY>. Note: You can also use a mnemonic seed instead of a private key by replacing the--private-keyoption with--mnemonic <YOUR_MNEMONIC>. -
This will deploy the DAO for you and output the addresses into a
migration.jsonfile.
const DAOstackMigration = require('@daostack/migration'); const options = { // arc version arcVersion: '0.0.1-rc.32', // web3 provider url provider: 'http://localhost:8545', // gas price in GWei. If not specified, will use an automatically suggested price. gasPrice: 3.4, // surpress console output quiet: true, // disable confirmation messages force: true, // delete previous deployment state and starts with clean state restart: false, // filepath to output the migration results output: 'migration.json', // private key of the account used in migration (overrides the 'mnemonic' option) privateKey: '0x123...', // mnemonic used to generate the private key of the account used in migration mnemonic: 'one two three ...', // migration parameters params: { default: { // migration params as defined in the "Migration parameters" section below }, private: { // override defaults on private network }, kovan: { // override defaults on kovan } } }; const migrationDAOResult = await DAOstackMigration.migrateDAO(options); migrationDAOResult.dao.Avatar; // DAO avatar address // migrate an demo test scenario (requires an existing `output` file with a base migration) const migrationDemoResult = await DAOstackMigration.migrateDemoTest(options); migrationDemoResult.test.Avatar; // Test DAO avatar address // migrate base, example DAO and demo test contracts const migrationResult = await DAOstackMigration.migrate(options); // migrate // run the cli DAOstackMigration.cli();docker pull daostack/migration- Run:
docker run --rm --name=ganache daostack/migration:0.0.0-alpha.56-v7 <ganache-cli arguments> - Fetch migration result file:
docker exec ganache cat migration.json - Fetch migration params file:
docker exec ganache cat migration-params.json
Example migration result object:
{ "base": { "DAOToken": "0x123...", "ControllerCreator": "0x123...", "DaoCreator": "0x123...", "UController": "0x123...", "GenesisProtocol": "0x123...", "SchemeRegistrar": "0x123...", "UpgradeScheme": "0x123...", "GlobalConstraintRegistrar": "0x123...", "ContributionReward": "0x123...", "AbsoluteVote": "0x123...", "QuorumVote": "0x123...", "TokenCapGC": "0x123...", "VestingScheme": "0x123...", "VoteInOrganizationScheme": "0x123...", "OrganizationRegister": "0x123...", "Redeemer": "0x123..." }, "dao": { "name": "DAO Jones", "Avatar": "0x123...", "NativeToken": "0x123...", "NativeReputation": "0x123..." }, "test": { "name": "0x123...", "Avatar": "0x123...", "NativeToken": "0x123...", "NativeReputation": "0x123...", "proposalId": "0xabc..." } }Example migration parameters object:
{ "orgName": "The DAO", // Sets the name of your DAO "tokenName": "The DAO Token", // Sets the name of your DAO token "tokenSymbol": "TDT", // Sets the name of your DAO token symbol // Needed only if you would like to use Contribution Reward scheme in your DAO "ContributionReward": [{ "voteParams": 0 // The index of the parameters in the voting machines parameters array }], // Needed only if you would like to use Generic Scheme scheme in your DAO "GenericScheme": [{ // The address of the contract the Generic Scheme can call. "targetContract": "0x0000000000000000000000000000000000000000" "votingMachine": "0x00000000000000000000votingmachineaddress" // The address of your voting machine (default is Genesis Protocol address) "voteParams": 1 // The index of the parameters in the voting machines parameters array (default is 0) }], // Allow you to deploy and call any contract you might need during the migration "StandAloneContracts":[ { "name": "Reputation", // If the contract isnot from Arc you must have the contract data (ABI + Bytecode) as a JSON file with the same name as the scheme "fromArc": true, // Add here any calls to the contract you want to execute "runFunctions": [ { "functionName": "transferOwnership", "params": [ "AvatarAddress" ] } ] }, { "name": "RepAllocation", // If your contract has an initialize / constructor method which accepts arguments please add them here. // unset constructor if using initialize "constructor": false, "params": [ 100000, { "StandAloneContract": 0 } ], "fromArc": true, // Optional. Allows to use a specific Arc version for the StandAloneContract contract, default: Arc version of the DAO. "arcVersion": "0.0.1-rc.30" } ], // Allows you to register and deploy custom schemes "CustomSchemes": { // You should have an contract build file with identical name inside `custom-abis` folder "MyCustomScheme": [ { // If true will call setParameters() else will call initialized() with the avatar address as a first parameter "isUniversal": true, // Parameters to use in the setParameters() / initialized() method "params": [ // An object like this { "voteParams": X } is transformed as the voting params hash like "voteParams": 0 in the supported schemes { "voteParams": 0 }, // This will be converted to the actual Genesis Protocol address "GenesisProtocolAddress", // You can also add literal parameters like so "anotherParam" ], // If the scheme is deployed set the address here, if not remove the field and the script will deploy the scheme // Can also use an address from the Standalone contracts like so: "address": { "StandAloneContract": 0 } "address": "0xaddress...", // The permissions your scheme need from the controller "permissions": "0x00000001", // Optional. Allows to use a specific Arc version for the CustomScheme contract, default: Arc version of the DAO. "arcVersion": "0.0.1-rc.30" }, { "name": "ContinuousLocking4Reputation", "schemeName": "ContinuousLocking4Reputation", "isUniversal": false, "params": [ "CONTINUES_LOCKING_REP_ALLOCATION", // How much Reputation should the scheme allocate. "START_TIME", // Start time for the locking as UNIX Timestamp (in seconds). "BATCH_TIME", // Time per batch (in seconds) "REDEEM_TIME", // Start time for redeeming as UNIX Timestamp (in seconds). "BATCHES_COUNT", // Number of batches "REP_REWARD_CONST_A", // repRewardConstA "REP_REWARD_CONST_B", // repRewardConstB "BATCHES_INDEX_CAP", // batchesIndexCap "TOKEN_ADDRESS", // Address of the token to lock. "AGREEMENT_HASH" // IPFS hash of user agreement. Can be arbitrary (for example: "0x1000000000000000000000000000000000000000000000000000000000000000") if not used. ], "permissions": "0x00000010", "alias": "InfiniteReputation4Token", "fromArc": true } ] }, // Parameters list your DAO will use with the voting machines // You can add here either Genesis Protocol parameters which will set the parameters in the GP voting machine or add a pre-set parameters hash to any voting machine "VotingMachinesParams": [ { "boostedVotePeriodLimit": 600, "daoBountyConst": 10, "minimumDaoBounty": 100, "queuedVotePeriodLimit": 1800, "queuedVoteRequiredPercentage": 50, "preBoostedVotePeriodLimit": 600, "proposingRepReward": 5, "quietEndingPeriod": 300, "thresholdConst": 2000, "voteOnBehalf": "0x0000000000000000000000000000000000000000", "votersReputationLossRatio": 1, "activationTime": 0 }, { "votingParamsHash": "0x000000000000000000000000000000paramshash" // If you want to use a different voting machine params you can set the parameters hash here } ], // Select the schemes you would like your DAO to have "schemes": { "ContributionReward": true, "GenericScheme": false, "SchemeRegistrar": true, "GlobalConstraintRegistrar": true, "UpgradeScheme": true }, // If true, the permission of the account which was used to deploy the DAO will // be revoked at the end of the deployment process "unregisterOwner": true, // True if should use Universal Controller (default false). "useUController": false, // True if should use the DAO Creator to deploy the DAO (default false). "useDaoCreator": false, // If not using DaoCreator, set to true to prevent automatic tracking on DAOTracker, otherwise the DAO will be tracked as part of the script "noTrack": false, // Allows to specify which Arc version should be used to deploy the dao. // This will override the version specified in the CLI flag. "arcVersion": "0.0.1-rc.30", // List of addresses to mint initial tokens and reputation to "founders": [ { "address": "0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1", "tokens": 1000, "reputation": 1000 }, { "address": "0xffcf8fdee72ac11b5c542428b35eef5769c409f0", "tokens": 1000, "reputation": 1000 }, { "address": "0x22d491bde2303f2f43325b2108d26f1eaba1e32b", "tokens": 1000, "reputation": 1000 }, { "address": "0xe11ba2b4d45eaed5996cd0823791e0c93114882d", "tokens": 1000, "reputation": 1000 }, { "address": "0xd03ea8624c8c5987235048901fb614fdca89b117", "tokens": 1000, "reputation": 1000 }, { "address": "0x95ced938f7991cd0dfcb48f0a06a40fa1af46ebc", "tokens": 1000, "reputation": 1000 } ] }git clone https://github.com/daostack/migration.git && cd migrationnpm install- Install
Dockerandjq
cleandb- rm the existing local db.ganache- run a ganache instance with local db.migrate ...- run migration (same arguments as cli)docker:build- build the docker image from current directory (make sure all to migrate on a fresh ganache beforehand)docker:push- push docker image to DockerHub.release ...- fully release a version (requires an.envfile withkovan_providerandkovan_private_keyvariables set) (same arguments as cli)
In order to release a version:
-
In one terminal tab:
npm run cleandb- Clean any existing ganache DB.npm run ganache- Run a ganache, creating a fresh DB.
-
In the another terminal tab:
-
Make sure you have the required
.envvariables set (kovan_provider,kovan_private_key,rinkeby_provider,rinkeby_private_key,mainnet_provider,mainnet_private_key). It should look something like this:kovan_provider="https://kovan.infura.io/v3/<YOUR_INFURA_KEY>" kovan_private_key="0x<YOUR_PRIVATE_KEY>" rinkeby_provider="https://rinkeby.infura.io/v3/<YOUR_INFURA_KEY>" rinkeby_private_key="0x<YOUR_PRIVATE_KEY>" mainnet_provider="https://mainnet.infura.io/v3/<YOUR_INFURA_KEY>" mainnet_private_key="0x<YOUR_PRIVATE_KEY>" xdai_provider="https://poa.api.nodesmith.io/v1/dai/jsonrpc?apiKey=<YOUR_XDAI_KEY>" xdai_private_key="0x<YOUR_PRIVATE_KEY>" sokol_provider="https://sokol.poa.network" sokol_private_key="0x<YOUR_PRIVATE_KEY>"
Note: Make sure you have enough ETH(or xDAI for the case of xDai/ SPOA in the case of Sokol) in the account corresponding to the private key you will use to pay the deployment gas costs.
-
Make sure you are not on the
masterbranch. If needed, create a new branch for the release process. -
npm run prepare-release- This will perform all the necessary steps to update version and prepare for a new release. The changes made here will be committed to the git branch. -
Create a PR and merge the new branch with the changes into
master. -
Make sure that you have a Dockerhub ID with permission to push an image to the
daostackorganization. -
Make sure that you have an
npmaccount with permission to push an image to thedaostackorganization. -
Make sure to be on the
masterbranch and runnpm run release- this will publish the new version to NPM and Dockerhub.
-