@daostack/migration
v0.0.1-rc.57-v1
Published
A repo for handling DAOstack contract migrations
Downloads
323
Readme
DAOstack 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/arc
package. - DAO migration - of an example DAO.
Versioning
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>
Usage
As a library
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()
As a 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]
How to deploying a new DAO:
From CLI:
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 -v
and 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.json
file, you can also use the samemigration-params.json
from the DAOstack migratio GitHub repo.Customize
your-new-dao-params.json
by 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-key
option with--mnemonic <YOUR_MNEMONIC>
.This will deploy the DAO for you and output the addresses into a
migration.json
file.
From Javascript
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();
As a docker image
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
Migration result
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..."
}
}
Migration parameters
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
}
]
}
Develop
Commands
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.env
file withkovan_provider
andkovan_private_key
variables set) (same arguments as cli)
How to release a version?
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
.env
variables 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
master
branch. 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
daostack
organization.Make sure that you have an
npm
account with permission to push an image to thedaostack
organization.Make sure to be on the
master
branch and runnpm run release
- this will publish the new version to NPM and Dockerhub.