从Dao聊到Aragon

dde700da3abad6de77c8d3377f6e2af2.gif

前言

之前两篇(浅谈区块链DAPP学习 和 浅谈区块链DAPP学习·续),我们聊了DAPP以及DAPP的一个简单的投票实现,可能还是有很多非技术类的朋友,他们不理解web3.0这样一种可以拥有的网络到底有什么用。

这一篇我准备拿现在国外这几年比较流行DAO聊一下web3.0的未来应用。

8bc5e1bd738ffdbdace90f7dad5716b1.png

首先什么是DAO

DAO是 Decentralized Autonomous Organization 的简写,即去中心化自治组织,有时也被称为分布式自治公司(DAC);有共同的目标或是共识,有明确的核心价值观。它的民主化的投票机制,决定了组织的方向和运作方式。

DAO的意义

eddc95ee50ce7e204911ec4deabbc992.png

首先DAO是用智能合约和开源编码的。该组织所做的是完全透明的。决策是通过DAO成员的基层投票做出的。在这样一种公开公平的区块链技术加持下,我们可以在互联网上成立各种不需要见面但可以为一个共同目标而努力的组织。

很魔幻,但在当下疫情肆虐的情况下却有着他生长的基础,元宇宙大概率会在DAO的基础上结合其他技术慢慢成长或是快速成长。

DAO的项目

9044b12e4bc73c1dc9a7daad91d90f31.png

理论上,任何组织都可以是DAO。投资DAO和赠款DAO可以资助项目。收藏家DAO可以收集NFT数字艺术和其他收藏品。社交DAO可以为其成员提供一定的社交圈。c476f41b937cbffec3199fc124a28a84.png

DAO Operation Systems

作为技术我不像做预言家,我还是切入我文章的主题,去介绍DAO的技术(DAO Operation Systems),相关的技术蛮多的。

好在区块链要用智能合约管理加密货币,所以你要通过合约审核必须开源,我们能找到很多国外关于DAO的技术,今天我就来介绍一下ARAGON这个项目。

什么是ARAGON

Aragon使用区块链来提高公司和组织的效率和透明度。公司可以使用Aragon彼此签署智能合约协议,然后可以将它们安全地存储在区块链上,以供任何一方在需要时访问。

Aragon喜欢视自己为数字司法管辖区。该网络正在创建一个去中心化的结算系统,该系统可用于在相关各方之间快速有效地进行仲裁。该平台具有自己的Token 令牌 Aragon Network Token - 简称“ANT” - 用于支付费用,并托管在第三方中以提供激励给良好诚实的用户行为。

如何开始一个ARAGON

首先https://aragon.org/是他的官网,你可以上官网创建自己的DAO组织df8f99949ddc16b02efdc29d8ce14cdc.png我们当然不会只使用他们官网来建立自己的DAO;使用他的技术架构才是我们的目的。

快速搭建ARAGON DAO本地架构

首先来到ARAGON GITHUB

https://github.com/aragon/

找到aragon-cli项目

https://github.com/aragon/aragon-cli
首先全局安装aragon/cli
npm install --global @aragon/cli
npm install --global @aragon/cli@nightly
创建你第一个ARAGON DAO项目
npx create-aragon-app myapp
cd myapp
npm start

项目打开后会用默认浏览器打开 http://localhost:3000/0b79a71af800287ceb2a57b4e852aa65.png可以看到启动了一个ganache初始化了8个账号;以及ENS,DAO APM等的address;简单的说他初始化了一个aragon的本地环境。eb343e8d680dab58aac3dc8df780c6e0.png从右上角看默认链接了本地ganache的钱包,同时已经显示了本地钱包的地址。d5db6c7b7c15e439e5b11a53324d52c4.png

代码分析

c43f3455820161a42124cf1bb5fb58df.png看了以后大家会发现和我们以前的结构很类似contracts下有个CounterApp.sol合约

pragma solidity ^0.4.24;

import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/lib/math/SafeMath.sol";

contract CounterApp is AragonApp {
    using SafeMath for uint256;

    /// Events
    event Increment(address indexed entity, uint256 step);
    event Decrement(address indexed entity, uint256 step);

    /// State
    uint256 public value;

    /// ACL
    bytes32 constant public INCREMENT_ROLE = keccak256("INCREMENT_ROLE");
    bytes32 constant public DECREMENT_ROLE = keccak256("DECREMENT_ROLE");

    function initialize(uint256 _initValue) public onlyInit {
        value = _initValue;

        initialized();
    }

    /**
     * @notice Increment the counter by `step`
     * @param step Amount to increment by
     */
    function increment(uint256 step) external auth(INCREMENT_ROLE) {
        value = value.add(step);
        emit Increment(msg.sender, step);
    }

    /**
     * @notice Decrement the counter by `step`
     * @param step Amount to decrement by
     */
    function decrement(uint256 step) external auth(DECREMENT_ROLE) {
        value = value.sub(step);
        emit Decrement(msg.sender, step);
    }
}

这个就是一个计数合约加减两个功能,其实和原来投票几乎一样,少了个身份认证,可以从上一篇加进来相关代码来不足。

8c34086ca33babecbf641382dfe3a2c6.png

scripts目录下 buidler-hooks.js 这些钩子由 Aragon Buidler 插件在start任务的生命周期中调用的,结合buidler配置文件(buidler.config.js)部署和挂钩合约。

const { usePlugin } = require('@nomiclabs/buidler/config')
const hooks = require('./scripts/buidler-hooks')

usePlugin('@aragon/buidler-aragon')

module.exports = {
  // Default Buidler configurations. Read more about it at https://buidler.dev/config/
  defaultNetwork: 'localhost',
  networks: {
    localhost: {
      url: 'http://localhost:8545',
    },
  },
  solc: {
    version: '0.4.24',
    optimizer: {
      enabled: true,
      runs: 10000,
    },
  },
  // Etherscan plugin configuration. Learn more at https://github.com/nomiclabs/buidler/tree/master/packages/buidler-etherscan
  etherscan: {
    apiKey: '', // API Key for smart contract verification. Get yours at https://etherscan.io/apis
  },
  // Aragon plugin configuration
  aragon: {
    appServePort: 8001,
    clientServePort: 3000,
    appSrcPath: 'app/',
    appBuildOutputPath: 'dist/',
    appName: 'myapp',
    hooks, // Path to script hooks
  },
}

buidler.config.js代码可见默认是链接本地localhost的ganache 并部署相关合约。

946bfdda6826c9abc45f65e1cd123ad3.png

src目录下的App.js

import { useAragonApi } from '@aragon/api-react'

const { api, appState, path, requestPath } = useAragonApi()
const { count, isSyncing } = appState

很清楚是通过 useAragonApi 去获得 api 方法和 appState 的 count 值的 附上 app.js 源码

import React from 'react'
import { useAragonApi } from '@aragon/api-react'
import {
  Box,
  Button,
  GU,
  Header,
  IconMinus,
  IconPlus,
  Main,
  SyncIndicator,
  Tabs,
  Text,
  textStyle,
} from '@aragon/ui'
import styled from 'styled-components'

function App() {
  const { api, appState, path, requestPath } = useAragonApi()
  const { count, isSyncing } = appState

  const pathParts = path.match(/^\/tab\/([0-9]+)/)
  const pageIndex = Array.isArray(pathParts)
    ? parseInt(pathParts[1], 10) - 1
    : 0

  return (
    <Main>
      {isSyncing && <SyncIndicator />}
      <Header
        primary="Counter"
        secondary={
          <span
            css={`
              ${textStyle('title2')}
            `}
          >
            {count}
          </span>
        }
      />
      <Tabs
        items={['Tab 1', 'Tab 2']}
        selected={pageIndex}
        onChange={index => requestPath(`/tab/${index + 1}`)}
      />
      <Box
        css={`
          display: flex;
          align-items: center;
          justify-content: center;
          text-align: center;
          height: ${50 * GU}px;
          ${textStyle('title3')};
        `}
      >
        Count: {count}
        <Buttons>
          <Button
            display="icon"
            icon={<IconMinus />}
            label="Decrement"
            onClick={() => api.decrement(1).toPromise()}
          />
          <Button
            display="icon"
            icon={<IconPlus />}
            label="Increment"
            onClick={() => api.increment(1).toPromise()}
            css={`
              margin-left: ${2 * GU}px;
            `}
          />
        </Buttons>
      </Box>
    </Main>
  )
}

const Buttons = styled.div`
  display: grid;
  grid-auto-flow: column;
  grid-gap: 40px;
  margin-top: 20px;
`

export default App

api.decrement(1).toPromise() api.increment(1).toPromise() 两个方法调用加减来实现合约接口的,821f734740af003d572087b24adf3676.png点击加号或减号c67f6b9501cc9156074d02d9b94b7d7c.png功能就这么简单的完成了,用它改建一个投票是非常简单的。

部署aragon

除了这样一步步,能快速部署aragon的功能官网部分功能吗?可以

mkdir aragon
npm init
npm install @aragon/aragen
npx aragen start
572bb865e2e4f1b31ba93c3ae36d5437.png

可以看到初始化了一个aragon的ganache环境。

其中就包括了:ENS instance deployed at: 0x5f6f7e8cc7346a11ca2def8f827b7a0b612c56a1(use-token:用于获取以太坊上代币相关信息的 React 实用程序,包括相关合约)。

启动client项目

首先来到ARAGON GITHUB找到Aragon Client

https://github.com/aragon/client

下载项目进入项目根目录

yarn
npm run start:local

服务启动在:http://localhost:3000 在项目根目录下有个arapp.json里面的内容默认的是rpc网络也就是本地网络localhost:8545

"environments": {
    "default": {
      "registry": "0x5f6f7e8cc7346a11ca2def8f827b7a0b612c56a1",
      "appName": "aragon.aragonpm.eth",
      "network": "rpc"
    },

他的registry address和aragon启动的网络是一样的

80d8be1674231bb9df8ff859e8055c2e.png

现在打开http://localhost:3000

aea0e303c10655d0b48e5d4d86a81244.png

改造钱包

右上角你会发现钱包无法连接本地链; 看来我们要改造他们项目的钱包了。 废话少说,在项目src/contexts/目录下有一个wellet.js附上代码

import React, {
  useContext,
  useEffect,
  useMemo,
  useCallback,
  useState,
} from 'react'
import PropTypes from 'prop-types'
import BN from 'bn.js'
import {
  useWallet as useWalletBase,
  UseWalletProvider,
  ChainUnsupportedError,
  chains,
} from 'use-wallet'
import { getWeb3, filterBalanceValue } from '../util/web3'
import { useWalletConnectors } from '../ethereum-providers/connectors'
import { useAPM, updateAPMContext } from './elasticAPM'
import { LocalStorageWrapper } from '../local-storage-wrapper'

export const WALLET_STATUS = Object.freeze({
  providers: 'providers',
  connecting: 'connecting',
  connected: 'connected',
  disconnected: 'disconnected',
  error: 'error',
})

// default network is mainnet if user is not connected
const NETWORK_TYPE_DEFAULT = chains.getChainInformation(1)?.type

const WalletContext = React.createContext()

function WalletContextProvider({ children }) {
  const {
    account,
    balance,
    ethereum,
    connector,
    status,
    chainId,
    providerInfo,
    type,
    networkName,
    ...walletBaseRest
  } = useWalletBase()

  const initialNetwork = useMemo(() => {
    const lastNetwork = LocalStorageWrapper.get('last-network', false)
    if (!lastNetwork) return NETWORK_TYPE_DEFAULT
    return lastNetwork
  }, [])

  const [walletWeb3, setWalletWeb3] = useState(null)
  const [disconnectedNetworkType, setDisconnectedNetworkType] = useState(
    initialNetwork
  )

  const connected = useMemo(() => status === 'connected', [status])
  const networkType = useMemo(() => {
    const newNetwork = connected ? networkName : disconnectedNetworkType
    LocalStorageWrapper.set('last-network', newNetwork, false)
    return newNetwork
  }, [connected, networkName, disconnectedNetworkType])

  const changeNetworkTypeDisconnected = useCallback(
    newNetworkType => {
      if (status === 'disconnected') {
        setDisconnectedNetworkType(newNetworkType)
      }
    },
    [status]
  )

  // get web3 and set local storage prefix whenever networkType changes
  useEffect(() => {
    let cancel = false

    if (!ethereum) {
      return
    }

    const walletWeb3 = getWeb3(ethereum)
    if (!cancel) {
      setWalletWeb3(walletWeb3)
    }

    return () => {
      cancel = true
      setWalletWeb3(null)
    }
  }, [ethereum, networkType])

  const wallet = useMemo(
    () => ({
      account,
      balance: new BN(filterBalanceValue(balance)),
      ethereum,
      networkType,
      providerInfo: providerInfo,
      web3: walletWeb3,
      status,
      chainId: connected ? chainId : 1, // connect to mainnet if wallet is not connected
      connected,
      changeNetworkTypeDisconnected,
      ...walletBaseRest,
    }),
    [
      account,
      balance,
      ethereum,
      networkType,
      providerInfo,
      status,
      chainId,
      walletBaseRest,
      walletWeb3,
      connected,
      changeNetworkTypeDisconnected,
    ]
  )

  const { apm } = useAPM()
  useEffect(() => {
    updateAPMContext(apm, wallet.networkType)
  }, [apm, wallet.networkType])

  return (
    <WalletContext.Provider value={wallet}>{children}</WalletContext.Provider>
  )
}
WalletContextProvider.propTypes = { children: PropTypes.node }

export function WalletProvider({ children }) {
  return (
    <UseWalletProvider connectors={useWalletConnectors} autoConnect>
      <WalletContextProvider>{children}</WalletContextProvider>
    </UseWalletProvider>
  )
}
WalletProvider.propTypes = { children: PropTypes.node }

export function useWallet() {
  return useContext(WalletContext)
}

export { ChainUnsupportedError }

连接本地钱包

经过一番仔细的阅读发觉钱包掉用的是'use-wallet',而且判断是否可以链接的代码在被调用的modules里,只有改了它才能本地部署aragon的本地client;use-wallet的源码地址

c5ffa17cec70798d1207bf246b29f241.png文件位置src/connectors/ConnectorInjected.ts

#添加的代码就这一段;这个就是添加钱包可以链接的本地chainId
chainId.push(1337)

配置本地EDC链

文件地址src/chains.ts,添加以下代码:

const EDC: Currency = {
  name: 'Ether',
  symbol: 'ETH',
  decimals: 18,
}
.....................
  [
    1337,
    {
      id: 1337,
      nativeCurrency: EDC,
      fullName: 'EDC',
      shortName: 'EDC',
      type: 'local',
      testnet: true,
    },
  ],

附上完整代码

import { ChainUnknownError } from './errors'
import { ChainInformation, ChainType, Currency } from './types'

const ETH: Currency = {
  name: 'Ether',
  symbol: 'ETH',
  decimals: 18,
}

const MATIC: Currency = {
  name: 'Matic Token',
  symbol: 'MATIC',
  decimals: 18,
}

const AVAX: Currency = {
  name: 'Avax',
  symbol: 'AVAX',
  decimals: 9,
}

const ONE: Currency = {
  name: 'ONE Token',
  symbol: 'ONE',
  decimals: 18,
}

const XDAI: Currency = {
  name: 'xDAI',
  symbol: 'xDAI',
  decimals: 18,
}

const BNB: Currency = {
  name: 'Binance Token',
  symbol: 'BNB',
  decimals: 18,
}

const TT: Currency = {
  name: 'Thunder Token',
  symbol: 'TT',
  decimals: 18,
}

const CELO: Currency = {
  name: 'Celo',
  symbol: 'CELO',
  decimals: 18,
}

const METIS: Currency = {
  name: 'METIS',
  symbol: 'METIS',
  decimals: 18,
}

const FTM: Currency = {
  name: 'FTM',
  symbol: 'FTM',
  decimals: 18,
}

const DEV: Currency = {
  name: 'DEV',
  symbol: 'DEV',
  decimals: 18,
}
const MOVR: Currency = {
  name: 'Moonriver',
  symbol: 'MOVR',
  decimals: 18,
}
const GLMR: Currency = {
  name: 'Glimmer',
  symbol: 'GLMR',
  decimals: 18,
}
const EDC: Currency = {
  name: 'Ether',
  symbol: 'ETH',
  decimals: 18,
}
const CHAIN_INFORMATION = new Map<number, ChainInformation | ChainType>([
  [
    1,
    {
      id: 1,
      nativeCurrency: ETH,
      type: 'main',
      fullName: 'Ethereum Mainnet',
      shortName: 'Ethereum',
      explorerUrl: `https://etherscan.io`,
      testnet: false,
    },
  ],
  [
    3,
    {
      id: 3,
      nativeCurrency: ETH,
      type: 'ropsten',
      fullName: 'Ropsten Testnet',
      shortName: 'Ropsten',
      explorerUrl: `https://ropsten.etherscan.io`,
      testnet: true,
    },
  ],
  [
    4,
    {
      id: 4,
      nativeCurrency: ETH,
      type: 'rinkeby',
      fullName: 'Rinkeby Testnet',
      shortName: 'Rinkeby',
      explorerUrl: `https://rinkeby.etherscan.io`,
      testnet: true,
    },
  ],
  [
    5,
    {
      id: 5,
      nativeCurrency: ETH,
      type: 'goerli',
      fullName: 'Goerli Testnet',
      shortName: 'Goerli',
      explorerUrl: `https://goerli.etherscan.io`,
      testnet: true,
    },
  ],
  [
    42,
    {
      id: 42,
      nativeCurrency: ETH,
      type: 'kovan',
      fullName: 'Kovan Testnet',
      shortName: 'Kovan',
      explorerUrl: `https://kovan.etherscan.io`,
      testnet: true,
    },
  ],
  [
    43112,
    {
      id: 43112,
      nativeCurrency: AVAX,
      type: 'avalocal',
      shortName: 'Avalanche Local',
      fullName: 'Avalanche Local',
      testnet: true,
    },
  ],
  [
    43113,
    {
      id: 43113,
      nativeCurrency: AVAX,
      type: 'fuji',
      fullName: 'Avalanche Fuji',
      shortName: 'Fuji',
      explorerUrl: 'https://testnet.snowtrace.io/',
      testnet: true,
    },
  ],
  [
    43114,
    {
      id: 43114,
      nativeCurrency: AVAX,
      type: 'avalanche',
      fullName: 'Avalanche Mainnet',
      shortName: 'Avalanche',
      explorerUrl: 'https://snowtrace.io/',
      testnet: false,
    },
  ],
  [
    100,
    {
      id: 100,
      nativeCurrency: XDAI,
      type: 'xdai',
      fullName: 'xDAI',
      shortName: 'xDAI',
      explorerUrl: 'https://blockscout.com/xdai/mainnet/',
      testnet: false,
    },
  ],
  [
    137,
    {
      id: 137,
      nativeCurrency: MATIC,
      type: 'matic',
      fullName: 'Polygon Mainnet',
      shortName: 'Polygon',
      explorerUrl: `https://polygonscan.com`,
      testnet: false,
    },
  ],
  [
    80001,
    {
      id: 80001,
      nativeCurrency: MATIC,
      type: 'mumbai',
      fullName: 'Mumbai Testnet',
      shortName: 'Mumbai',
      explorerUrl: `https://mumbai.polygonscan.com`,
      testnet: true,
    },
  ],
  [
    250,
    {
      id: 250,
      nativeCurrency: FTM,
      type: 'fantom',
      fullName: 'Fantom Opera Mainnet',
      shortName: 'FTM',
      explorerUrl: `https://ftmscan.com/`,
      testnet: false,
    },
  ],
  [
    1666600000,
    {
      id: 1666600000,
      nativeCurrency: ONE,
      type: 'harmony',
      fullName: 'Harmony ONE',
      shortName: 'Harmony',
      explorerUrl: `https://explorer.harmony.one/`,
      testnet: false,
    },
  ],
  [
    1666700000,
    {
      id: 1666700000,
      nativeCurrency: ONE,
      type: 'harmonyTest',
      fullName: 'Harmony ONE Testnet',
      shortName: 'Harmony Testnet',
      explorerUrl: `https://explorer.testnet.harmony.one/`,
      testnet: true,
    },
  ],
  [
    56,
    {
      id: 56,
      nativeCurrency: BNB,
      type: 'bsc',
      fullName: 'Binance Smart Chain',
      shortName: 'BSC',
      explorerUrl: `https://bscscan.com/`,
      testnet: false,
    },
  ],
  [
    97,
    {
      id: 97,
      nativeCurrency: BNB,
      type: 'bscTest',
      fullName: 'Binance Smart Chain Testnet',
      shortName: 'BSC Testnet',
      explorerUrl: `https://testnet.bscscan.com/`,
      testnet: true,
    },
  ],
  [
    108,
    {
      id: 108,
      nativeCurrency: TT,
      type: 'thundercore',
      fullName: 'ThunderCore Mainnet',
      shortName: 'ThunderCore',
      explorerUrl: `https://scan.thundercore.com/`,
      testnet: false,
    },
  ],
  [
    18,
    {
      id: 18,
      nativeCurrency: TT,
      type: 'thundercoreTest',
      fullName: 'ThunderCore Testnet',
      shortName: 'ThunderCore Testnet',
      explorerUrl: `https://scan-testnet.thundercore.com/`,
      testnet: true,
    },
  ],
  [
    421611,
    {
      id: 421611,
      nativeCurrency: ETH,
      type: 'arbitrumTest',
      fullName: 'Arbitrum Testnet',
      shortName: 'Arbitrum Testnet',
      explorerUrl: 'https://testnet.arbiscan.io/',
      testnet: true,
    },
  ],
  [
    42161,
    {
      id: 42161,
      nativeCurrency: ETH,
      type: 'arbitrum',
      fullName: 'Arbitrum Mainnet',
      shortName: 'Arbitrum',
      explorerUrl: 'https://arbiscan.io/',
      testnet: false,
    },
  ],
  [
    42220,
    {
      id: 42220,
      nativeCurrency: CELO,
      type: 'celo',
      fullName: 'Celo (Mainnet)',
      shortName: 'Celo',
      explorerUrl: 'https://explorer.celo.org/',
      testnet: false,
    },
  ],
  [
    44787,
    {
      id: 44787,
      nativeCurrency: CELO,
      type: 'celoTest',
      fullName: 'Celo (Alfajores Testnet)',
      shortName: 'Alfajores',
      explorerUrl: 'https://alfajores-blockscout.celo-testnet.org/',
      testnet: true,
    },
  ],
  [
    588,
    {
      id: 588,
      nativeCurrency: METIS,
      type: 'stardust',
      fullName: 'Metis Stardust Testnet',
      shortName: 'Stardust',
      explorerUrl: 'https://stardust-explorer.metis.io/',
      testnet: true,
    },
  ],
  [
    1088,
    {
      id: 1088,
      nativeCurrency: METIS,
      type: 'andromeda',
      fullName: 'Metis Andromeda',
      shortName: 'Andromeda',
      explorerUrl: 'https://andromeda-explorer.metis.io/',
      testnet: false,
    },
  ],
  [
    1313161555,
    {
      id: 1313161555,
      nativeCurrency: ETH,
      type: 'aurora',
      fullName: 'Aurora Testnet',
      shortName: 'AuroraTest',
      explorerUrl: 'https://explorer.testnet.aurora.dev/',
      testnet: true,
    },
  ],
  [
    1313161554,
    {
      id: 1313161554,
      nativeCurrency: ETH,
      type: 'aurora',
      fullName: 'Aurora Mainnet',
      shortName: 'Aurora',
      explorerUrl: 'https://explorer.mainnet.aurora.dev/',
      testnet: false,
    },
  ],
  [
    1287,
    {
      id: 1287,
      nativeCurrency: DEV,
      type: 'moonbase',
      fullName: 'moonbase',
      shortName: 'Moonbase Alphanet',
      explorerUrl: 'https://moonbase.moonscan.io/',
      testnet: true,
    },
  ],
  [
    1285,
    {
      id: 1285,
      nativeCurrency: MOVR,
      type: 'moonriver',
      fullName: 'Moonriver',
      shortName: 'Moonriver',
      explorerUrl: 'https://moonriver.moonscan.io/',
      testnet: false,
    },
  ],
  [
    1284,
    {
      id: 1284,
      nativeCurrency: GLMR,
      type: 'moonbeam',
      fullName: 'Moonbeam',
      shortName: 'Moonbeam',
      explorerUrl: 'https://moonbeam.moonscan.io/',
      testnet: false,
    },
  ],
  [
    1337,
    {
      id: 1337,
      nativeCurrency: EDC,
      fullName: 'EDC',
      shortName: 'EDC',
      type: 'local',
      testnet: true,
    },
  ],
  [
    5777,
    {
      id: 5777,
      type: 'ganache',
      testnet: true,
    },
  ],
])

/**
 * This method checks whether a particular chain id is known.
 *
 * @param {number} chainId chain id to check
 * @returns {boolean} true if chain is known
 */
export function isKnownChain(chainId: number): boolean {
  return CHAIN_INFORMATION.has(chainId)
}

/**
 *
 * @param {number} chainId chain id to retrieve information for
 * @throws {ChainUnknownError} if chain is unknown
 * @returns {boolean} information for specified chain
 */
export function getChainInformation(
  chainId: number
): ChainInformation | ChainType {
  const chainInfo = CHAIN_INFORMATION.get(chainId)
  if (!chainInfo) throw new ChainUnknownError(`Unknown chain id: ${chainId}`)
  return chainInfo
}

/**
 * This is a getter method to returns the chain ids of all known chains.
 *
 * @returns {number[]} array of chain Ids
 */
export function getKnownChainsIds(): number[] {
  return Array.from(CHAIN_INFORMATION.keys())
}

/**
 * This is a getter method to return all information available for each known chain.
 *
 * @returns {ChainInformation | ChainType[]} An array containing information for
 * each known chain
 */
export function getKnownChainInformation(): ChainInformation | ChainType[] {
  return Array.from(CHAIN_INFORMATION.values())
}

export function getDefaultChainId(): number {
  return 1
}

开始编译

yarn run build

build完成把dist目录下的文件复制到client项目node_modules/use-wallet/dist/下

配置client项目

  • src/network-config.js把 isActive: false,改成isActive: true,

  • ensRegistry: localEnsRegistryAddress,要改成(ensRegistry: localEnsRegistryAddress||"0x5f6f7e8cc7346a11ca2def8f827b7a0b612c56a1")

[chains.getChainInformation(1337).type]: {
    isActive: false,//就是这里
    addresses: {
      ensRegistry: localEnsRegistryAddress,
      governExecutorProxy: null,
    },
    nodes: {
      defaultEth: 'ws://localhost:8545',
    },
    connectGraphEndpoint: null,
    settings: {
      // Local development environments by convention use
      // a chainId of value 1337, but for the sake of configuration
      // we expose a way to change this value.
      chainId: 1337,
      testnet: true,
      ...chains.getChainInformation(1337),
      live: false,
    },
  },

运行前端页面

ffb208e5777e7d09aece011fa9077e4a.png

我们发现Testnets多了EDC,然后本地链的钱包链上了,可以尽情的玩他的功能不用胆心加密币不够了。

47155e5bbb838b81482cfac3c6c275f8.png

创建本地组织

下面演示本地创建一个组织的过程:5ec89ce89f5ac39442c14d278f836c06.png

点击 create

14f0e43b1114404f5d3c17b2d7a7935d.png点击membership

410ff883aa8cfb16cd908ba155f0bac1.png

点击 Use this template

63adf97c8ddbfa4b8747a25fdb3075e0.png

点击 next

8e7e2ce6af4492bf09ae2b6736ca79da.png

点击 next 输入一个本地账户地址

585d692158868855e3856fa521b51737.png

继续 next

79e205a2ea7cd71dc6c58a4305827551.pngba99d8bb7f5c2cde4538fe1ddf9e11c4.pngfeb18241bbc248adaf3c661f9c932e1d.pngfd6fc304c084093da51e952f184fb558.png

投票和转账功能

对的在这个组织里做什么都需要投票通过就算你转账也需要全员投票哦。

a86a1f820be5d7142d5fa903d59f0807.png7c54e50952c8e8ba8739ac36ba9c8e2a.png

小结

以上只是简单介绍了aragon部署,我们刚才没有用company原因我们没有部署合约;

  • 合约可以在dao-templates里下载部署有机会后面可以写一下;其实项目里的配置文件写的很清楚。

https://github.com/aragon/dao-templates
  • 还有就是我们用的都是aragon默认的ganache环境可以改吗?也可以aragen下载源码;

https://github.com/aragon/aragen
  • web3.0是python2的nodejs版本选择很重要;

  • 项目会自动下载所有主要项目,其中几个项目的环境有差异,但可以分块切换环境部署,

  • 还有就是ipfs其实很多图片都存在ipfs里需要本地部署的通过aragon项目发布到ipfs本地服务上;

  • ipfs官网地址,

https://docs.ipfs.io/install/command-line/#official-distributions

不多说了,其实还有很多技术细节还没写完,本人技术也有限,有什么错漏的希望大家指正。

猜你喜欢

转载自blog.csdn.net/weixin_47479625/article/details/124113850
DAO